using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace PDF_Master.Helper
{
///
/// 设置成默认阅读器的辅助类
///
public static class Win32Helper
{
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[Flags]
public enum HChangeNotifyEventID
{
SHCNE_ALLEVENTS = 0x7FFFFFFF,
SHCNE_ASSOCCHANGED = 0x08000000,
SHCNE_ATTRIBUTES = 0x00000800,
SHCNE_CREATE = 0x00000002,
SHCNE_DELETE = 0x00000004,
SHCNE_DRIVEADD = 0x00000100,
SHCNE_DRIVEADDGUI = 0x00010000,
SHCNE_DRIVEREMOVED = 0x00000080,
SHCNE_EXTENDED_EVENT = 0x04000000,
SHCNE_FREESPACE = 0x00040000,
SHCNE_MEDIAINSERTED = 0x00000020,
SHCNE_MEDIAREMOVED = 0x00000040,
SHCNE_MKDIR = 0x00000008,
SHCNE_NETSHARE = 0x00000200,
SHCNE_NETUNSHARE = 0x00000400,
SHCNE_RENAMEFOLDER = 0x00020000,
SHCNE_RENAMEITEM = 0x00000001,
SHCNE_RMDIR = 0x00000010,
SHCNE_SERVERDISCONNECT = 0x00004000,
SHCNE_UPDATEDIR = 0x00001000,
SHCNE_UPDATEIMAGE = 0x00008000,
}
[Flags]
public enum HChangeNotifyFlags
{
SHCNF_DWORD = 0x0003,
SHCNF_IDLIST = 0x0000,
SHCNF_PATHA = 0x0001,
SHCNF_PATHW = 0x0005,
SHCNF_PRINTERA = 0x0002,
SHCNF_PRINTERW = 0x0006,
SHCNF_FLUSH = 0x1000,
SHCNF_FLUSHNOWAIT = 0x2000
}
[Flags]
public enum FileMapProtection : uint
{
PageReadonly = 0x02,
PageReadWrite = 0x04,
PageWriteCopy = 0x08,
PageExecuteRead = 0x20,
PageExecuteReadWrite = 0x40,
SectionCommit = 0x8000000,
SectionImage = 0x1000000,
SectionNoCache = 0x10000000,
SectionReserve = 0x4000000,
}
[Flags]
public enum FileMapAccessType : uint
{
Copy = 0x01,
Write = 0x02,
Read = 0x04,
AllAccess = 0x08,
Execute = 0x20,
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint GetModuleFileName([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In][MarshalAs(UnmanagedType.U4)] int nSize);
[DllImport("kernel32.dll")]
public static extern void ExitProcess(uint uExitCode);
[DllImport("shell32.dll")]
static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, IntPtr dwItem1, IntPtr dwItem2);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool SetEvent(IntPtr hEvent);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, FileMapProtection flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, [MarshalAs(UnmanagedType.LPStr)] string lpName);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr MapViewOfFileEx(IntPtr hFileMappingObject, FileMapAccessType dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap, IntPtr lpBaseAddress);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr OpenFileMapping(int dwDesiredAccess, int bInheritHandle, [MarshalAs(UnmanagedType.LPStr)] string lpName);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);
///
/// 注册为默认PDF浏览器
///
///
///
public static bool RegisterDefaultApp(bool isDefault)
{
bool isWin8OrHigher = false;
if (Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor > 1))
{
isWin8OrHigher = true;
}
try
{
AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
/*********** register APP Path *******************/
RegistryKey appPathKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths", true);
if (appPathKey == null)
{
return false;
}
RegistryKey appKey = appPathKey.CreateSubKey(assemblyName.Name + ".exe");
if (appKey != null)
{
appKey.SetValue("", Assembly.GetExecutingAssembly().Location);
appKey.SetValue("Path", Directory.GetParent(assemblyName.FullName).FullName);
appKey.Close();
}
appPathKey.Close();
/*********** register ProgID *******************/
RegistryKey progIdKey = Registry.ClassesRoot.CreateSubKey(assemblyName.Name + ".pdf.1");
if (progIdKey == null)
{
return false;
}
progIdKey.SetValue("", assemblyName.Name);
RegistryKey openKey = progIdKey.CreateSubKey("Shell\\Open\\Command");
openKey.SetValue("", Assembly.GetExecutingAssembly().Location + " \"%s\" \"%1\"");
openKey.Close();
progIdKey.Close();
/*********** register Default File Association *******************/
RegistryKey softwareKey = Registry.LocalMachine.CreateSubKey("Software\\" + assemblyName.Name);
if (softwareKey == null)
{
return false;
}
RegistryKey capabKey = softwareKey.CreateSubKey("Capabilities\\FileAssociations");
capabKey.SetValue(".pdf", assemblyName.Name + ".pdf.1");
capabKey.Close();
capabKey = softwareKey.CreateSubKey("Capabilities", true);
capabKey.SetValue("ApplicationDescription", assemblyName.Name);
capabKey.Close();
softwareKey.Close();
/*********** register Default App List *******************/
RegistryKey regiserAppKeys = Registry.LocalMachine.OpenSubKey("SOFTWARE\\RegisteredApplications", true);
if (regiserAppKeys == null)
{
return false;
}
regiserAppKeys.SetValue(assemblyName.Name, "SOFTWARE\\" + assemblyName.Name + "\\Capabilities");
regiserAppKeys.Close();
Registry.ClassesRoot.SetValue(".pdf", assemblyName.Name + ".pdf.1");
if (isDefault)
{
if (isWin8OrHigher)
{
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
pSec.nLength = Marshal.SizeOf(pSec);
tSec.nLength = Marshal.SizeOf(tSec);
string commandLine = " \".pdf\" \"" + assemblyName.Name + ".pdf.1\"";
CreateProcess("Resources\\exe\\SFTA.exe", commandLine, ref pSec, ref tSec, false, 0, IntPtr.Zero, null, ref sInfo, out pInfo);
WaitForSingleObject(pInfo.hProcess, 3000);
}
else
{
RegistryKey defaultKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.pdf\\UserChoice", true);
defaultKey.SetValue("ProgId", assemblyName.Name + ".pdf.1");
defaultKey.Close();
SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
}
}
else
{
RegistryKey defaultKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.pdf", true);
RegistryKey userChoice = defaultKey.OpenSubKey("UserChoice");
string checkId = userChoice.GetValue("ProgId").ToString();
if (checkId == (assemblyName.Name + ".pdf.1") || checkId == "PDF Technologies, Inc..PDF Master")
{
defaultKey.DeleteSubKey("UserChoice");
SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
}
defaultKey.Close();
}
return true;
}
catch
{
}
return false;
}
///
/// 判断是否是默认pdf阅读器
///
///
public static bool IsDefaultApp()
{
try
{
AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
var asm = Assembly.GetExecutingAssembly();
RegistryKey defaultKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.pdf\\UserChoice");
AssemblyCompanyAttribute asmcpn = (AssemblyCompanyAttribute)Attribute.GetCustomAttribute(asm, typeof(AssemblyCompanyAttribute));
AssemblyProductAttribute aspro = (AssemblyProductAttribute)Attribute.GetCustomAttribute(asm, typeof(AssemblyProductAttribute));
string id = string.Format("{0}.{1}", asmcpn.Company, aspro.Product);
if (defaultKey != null)
{
string checkId = defaultKey.GetValue("ProgId").ToString();
if (checkId == "PDF Technologies, Inc..PDF Reader Pro" || checkId == id)
{
return true;
}
defaultKey.Close();
if (checkId == (assemblyName.Name + ".pdf.1"))
{
return true;
}
}
}
catch { }
return false;
}
///
/// 判断当前程序是否以管理员身份运行
///
///
public static bool IsRunAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
}