fix encoding filename

This commit is contained in:
zhuangkh 2021-12-28 23:59:05 +08:00
parent faa9a059bc
commit 1151cbb42f
10 changed files with 322 additions and 28 deletions

View File

@ -18,16 +18,20 @@ namespace PdfScribe
/// <summary>
/// Calls the Ghostscript API with a collection of arguments to be passed to it
/// </summary>
public static void CallAPI(string[] args)
public static void CallAPI(string[] argv)
{
// Get a pointer to an instance of the Ghostscript API and run the API with the current arguments
IntPtr gsInstancePtr;
lock (resourceLock)
{
NativeMethods.CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
IntPtr[] utf8argv = new IntPtr[argv.Length];
for (int i = 0; i < utf8argv.Length; i++)
utf8argv[i] = NativeMethods.NativeUtf8FromString(argv[i]);
try
{
int result = NativeMethods.InitAPI(gsInstancePtr, args.Length, args);
NativeMethods.SetEncoding(gsInstancePtr, NativeMethods.GS_ARG_ENCODING_UTF8);
int result = NativeMethods.InitAPI(gsInstancePtr, argv.Length, utf8argv);
if (result < 0)
{
@ -36,6 +40,8 @@ namespace PdfScribe
}
finally
{
for (int i = 0; i < utf8argv.Length; i++)
Marshal.FreeHGlobal(utf8argv[i]);
Cleanup(gsInstancePtr);
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace PdfScribe
{
@ -13,12 +14,18 @@ namespace PdfScribe
https://github.com/mephraim/ghostscriptsharp
*/
public const int GS_ARG_ENCODING_LOCAL = 0;
public const int GS_ARG_ENCODING_UTF8 = 1;
#region Hooks into Ghostscript DLL
[DllImport("gsdll64.dll", EntryPoint = "gsapi_new_instance")]
internal static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);
[DllImport("gsdll64.dll", EntryPoint = "gsapi_init_with_args")]
internal static extern int InitAPI(IntPtr instance, int argc, string[] argv);
internal static extern int InitAPI(IntPtr instance, int argc, IntPtr[] argv);
[DllImport("gsdll64.dll", EntryPoint = "gsapi_set_arg_encoding")]
internal static extern int SetEncoding(IntPtr inst, int encoding);
[DllImport("gsdll64.dll", EntryPoint = "gsapi_exit")]
internal static extern int ExitAPI(IntPtr instance);
@ -29,5 +36,15 @@ namespace PdfScribe
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetDllDirectory(string lpPathName);
public static IntPtr NativeUtf8FromString(string managedString)
{
int len = Encoding.UTF8.GetByteCount(managedString);
byte[] buffer = new byte[len + 1]; // null-terminator allocated
Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
IntPtr nativeUtf8 = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, nativeUtf8, buffer.Length);
return nativeUtf8;
}
}
}

View File

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PdfScribe</RootNamespace>
<AssemblyName>PdfScribe</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
@ -87,6 +87,7 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
@ -114,6 +115,7 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="RegUtils.cs" />
<Compile Include="SetOutputFilename.cs">
<SubType>Form</SubType>
</Compile>

View File

@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
@ -42,6 +43,7 @@ namespace PdfScribe
[STAThread]
static void Main(string[] args)
{
//Debugger.Launch();
// Install the global exception handler
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException);
@ -66,8 +68,10 @@ namespace PdfScribe
File.Delete(outputFilename);
// Only set absolute minimum parameters, let the postscript input
// dictate as much as possible
String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite",
String.Format("-sOutputFile={0}", outputFilename), standardInputFilename,
outputFilename = outputFilename.Replace("\\\\", "/");
standardInputFilename = standardInputFilename.Replace("\\", "/");
string[] ghostScriptArguments = {"gs", "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite",
string.Format("-sOutputFile={0}", outputFilename), standardInputFilename,
"-c", @"[/Creator(PdfScribe 1.1.0 (PSCRIPT5)) /DOCINFO pdfmark", "-f"};
GhostScript64.CallAPI(ghostScriptArguments);
@ -229,8 +233,19 @@ namespace PdfScribe
}
private static void GetPathFormTitle(ref String outputFilename,
String standardInputFilename)
private static void GetPathFormTitle(ref String outputFilename, string standardInputFilename)
{
string path = RegUtils.GetRegistryValue("Software\\PDF Scribe uBIM_Customization", "OutputFile");
if (path != "0000")
{
var dir = path.Substring(0, path.LastIndexOf("\\") + 1);
var file = path.Substring(path.LastIndexOf("\\") + 1);
file = MakeValidFileName(file);
outputFilename = dir + file;
RegUtils.SetRegistryKey("HKEY_CURRENT_USER", "Software\\PDF Scribe uBIM_Customization", "OutputFile", "0000");
}
if (string.IsNullOrEmpty(outputFilename))
{
const String titlePrefix = "%%Title: ";
using (var fs = new FileStream(standardInputFilename, FileMode.Open, FileAccess.Read))
@ -241,13 +256,61 @@ namespace PdfScribe
{
if (line.StartsWith(titlePrefix))
{
outputFilename = line.Substring(titlePrefix.Length);
var file = line.Substring(titlePrefix.Length);
if (file.StartsWith("<"))
{
file = file.Trim('<', '>');
var length = file.Length;
var count = file.Length / 2;
for (int i = 1; i <= count; i++)
{
file = file.Insert(length - i * 2, "%");
}
file = System.Web.HttpUtility.UrlDecode(file, Encoding.GetEncoding("gb2312"));
}
file = file.Trim('(', ')');
if (file.Contains(@"\\"))
{
file = file.Replace(@"\\", @"//");
var oldStr = Regex.Matches(file, @"\\[0-9]{1,3}");
if (oldStr.Count > 0)
{
foreach (Match str in oldStr)
{
var num = str.Value.Trim('\\');
var hex = $"%{Convert.ToInt32(num, 8).ToString("X")}";
file = file.Replace(str.Value, hex);
}
file = System.Web.HttpUtility.UrlDecode(file, Encoding.GetEncoding("gb2312"));
}
file = file.Replace(@"//", @"\\");
}
if (!string.IsNullOrEmpty(Path.GetExtension(file)))
{
var dir = file.Substring(0, file.LastIndexOf("\\") + 1);
file = file.Substring(file.LastIndexOf("\\") + 1);
file = MakeValidFileName(file);
outputFilename = dir + file;
}
break;
}
}
}
}
}
private static string MakeValidFileName(string outputFilename, char replaceChar = '_')
{
var invalidChars = System.IO.Path.GetInvalidFileNameChars();
foreach (var invalidChar in invalidChars)
{
outputFilename = outputFilename.Replace(invalidChar, replaceChar);
}
return outputFilename;
}
private static String GetOutputFilename()
{
String outputFilename = Path.GetFullPath(Environment.ExpandEnvironmentVariables(Properties.Settings.Default.OutputFile));

206
PdfScribe/RegUtils.cs Normal file
View File

@ -0,0 +1,206 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
namespace PdfScribe
{
public static class RegUtils
{
static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000));
static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001));
static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003));
static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004));
static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005));
static readonly IntPtr HKEY_DYN_DATA = new IntPtr(unchecked((int)0x80000006));
// 获取操作Key值句柄
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult);
//创建或打开Key值
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegCreateKeyEx(IntPtr hKey, string lpSubKey, int reserved, string type, int dwOptions, int REGSAM, IntPtr lpSecurityAttributes, out IntPtr phkResult,
out int lpdwDisposition);
//关闭注册表转向(禁用特定项的注册表反射)
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegDisableReflectionKey(IntPtr hKey);
//使能注册表转向(开启特定项的注册表反射)
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegEnableReflectionKey(IntPtr hKey);
//获取Key值Key值句柄所标志的Key对象的值
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, out uint lpType, StringBuilder lpData, ref uint lpcbData);
//设置Key值
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegSetValueEx(IntPtr hKey, string lpValueName, uint unReserved, uint unType, byte[] lpData, uint dataCount);
//关闭Key值
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegCloseKey(IntPtr hKey);
public static IntPtr TransferKeyName(string keyName)
{
IntPtr ret = IntPtr.Zero;
switch (keyName)
{
case "HKEY_CLASSES_ROOT":
ret = HKEY_CLASSES_ROOT;
break;
case "HKEY_CURRENT_USER":
ret = HKEY_CURRENT_USER;
break;
case "HKEY_LOCAL_MACHINE":
ret = HKEY_LOCAL_MACHINE;
break;
case "HKEY_USERS":
ret = HKEY_USERS;
break;
case "HKEY_PERFORMANCE_DATA":
ret = HKEY_PERFORMANCE_DATA;
break;
case "HKEY_CURRENT_CONFIG":
ret = HKEY_CURRENT_CONFIG;
break;
case "HKEY_DYN_DATA":
ret = HKEY_DYN_DATA;
break;
default:
ret = HKEY_LOCAL_MACHINE;
break;
}
return ret;
}
/// <summary>
/// 设置64位注册表
/// </summary>
/// <param name="key"></param>
/// <param name="subKey"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public static int Set64BitRegistryKey(string key, string subKey, string name, string value)
{
int STANDARD_RIGHTS_ALL = 0x001F0000;
int KEY_QUERY_VALUE = 0x0001;
int KEY_SET_VALUE = 0x0002;
int KEY_CREATE_SUB_KEY = 0x0004;
int KEY_ENUMERATE_SUB_KEYS = 0x0008;
int KEY_NOTIFY = 0x0010;
int KEY_CREATE_LINK = 0x0020;
int SYNCHRONIZE = 0x00100000;
int KEY_WOW64_64KEY = 0x0100;
int REG_OPTION_NON_VOLATILE = 0x00000000;
int KEY_ALL_ACCESS = (STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS
| KEY_NOTIFY | KEY_CREATE_LINK) & ~SYNCHRONIZE;
int ret = 0;
try
{
//将Windows注册表主键名转化成为不带正负号的整形句柄与平台是32或者64位有关
IntPtr hKey = TransferKeyName(key);
//声明将要获取Key值的句柄
IntPtr pHKey = IntPtr.Zero;
//获得操作Key值的句柄
int lpdwDisposition = 0;
ret = RegCreateKeyEx(hKey, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, IntPtr.Zero, out pHKey, out lpdwDisposition);
if (ret != 0)
{
//Log2.Log(string.Format("Unable to create key {0} - {1}: {2}!", key, subKey, ret));
return ret;
}
//关闭注册表转向(禁止特定项的注册表反射)
RegDisableReflectionKey(pHKey);
//设置访问的Key值
uint REG_SZ = 1;
byte[] data = Encoding.Unicode.GetBytes(value);
RegSetValueEx(pHKey, name, 0, REG_SZ, data, (uint)data.Length);
//打开注册表转向(开启特定项的注册表反射)
RegEnableReflectionKey(pHKey);
RegCloseKey(pHKey);
}
catch (Exception ex)
{
//Log2.Log(ex.ToString());
return -1;
}
return ret;
}
public static void SetRegistryKey(string key, string subKey, string name, string value)
{
//Log2.Log("SetRegistryKey start.");
if (IntPtr.Size == 8)
{
// 写SOFTWARE\Huawei\VirtualDesktopAgent需要关闭注册表重定向再写64位路径的注册表
int ret = Set64BitRegistryKey(key, subKey, name, value);
if (ret != 0)
{
//Log2.Log(string.Format("Failed to write Reg {0}\\{1}\\{2},return {3}", key, subKey, name, ret));
}
}
try
{
Registry.SetValue(key + "\\" + subKey, name, value);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
//Log2.Log(ex.ToString());
}
//Log2.Log("SetRegistryKey exit.");
}
public static string GetRegistryValue(string path, string key)
{
RegistryKey regkey = null;
try
{
regkey = Registry.CurrentUser.OpenSubKey(path);
if (regkey == null)
{
//Log2.Log("Cannot find Registry path:" + path);
return null;
}
object val = regkey.GetValue(key);
if (val == null)
{
//Log2.Log("Cannot find Registry key:" + key);
return null;
}
return val.ToString();
}
catch (Exception ex)
{
//Log2.Log(ex.ToString());
return null;
}
finally
{
if (regkey != null)
{
regkey.Close();
}
}
}
}
}

View File

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PdfScribeCore</RootNamespace>
<AssemblyName>PdfScribeCore</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>

View File

@ -38,7 +38,7 @@ namespace PdfScribeCore
private readonly String logEventSourceNameDefault = "PdfScribeCore";
const string ENVIRONMENT_64 = "Windows x64";
const string PRINTERNAME = "PDF Scribe";
const string PRINTERNAME = "PDF Scribe uBIM_Customization";
const string DRIVERNAME = "PDF Scribe Virtual Printer";
const string HARDWAREID = "PDFScribe_Driver0101";
const string PORTMONITOR = "PDFSCRIBE";

View File

@ -6,7 +6,7 @@
<ProductVersion>3.7</ProductVersion>
<ProjectGuid>{3c255536-a7f1-4913-9c7f-966dffee01bc}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>PdfScribeInstall_1.1</OutputName>
<OutputName>PdfScribeInstall_1.1.2.413</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx ="http://schemas.microsoft.com/wix/NetFxExtension">
<Product Id="{8D75C14C-20BD-439D-826C-C399C13DEE31}" Name="PDF Scribe" Language="1033" Version="1.1.0" Manufacturer="Black Telescope Workshop" UpgradeCode="409ff0d1-1c3a-4f8d-8a5a-350705977809">
<Product Id="{4618E59F-753E-4DF0-8F14-6CD963C03EEA}" Name="PDF Scribe" Language="1033" Version="1.1.2.413" Manufacturer="Black Telescope Workshop" UpgradeCode="409ff0d1-1c3a-4f8d-8a5a-350705977809">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine"
Platform="x64"
InstallPrivileges="elevated"
Description="PDF Scribe Virtual Printer"
Comments="PDF Scribe Virtual Printer 1.1.0 installation package"
Comments="PDF Scribe Virtual Printer 1.1.2 installation package"
Id="*" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed."

View File

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PdfScribeInstallCustomAction</RootNamespace>
<AssemblyName>PdfScribeInstallCustomAction</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<WixCATargetsPath Condition=" '$(WixCATargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets</WixCATargetsPath>
<TargetFrameworkProfile />