예제 #1
0
        /// <summary>
        /// Adds a new print driver in the system
        /// </summary>
        /// <param name="configFile"> The config file. </param>
        /// <param name="dataFile"> The data file. </param>
        /// <param name="dependentFiles"> The dependent files. </param>
        /// <param name="driverPath"> The driver path. </param>
        /// <param name="driverName"> The driver name. </param>
        /// <param name="environment"> The environment. </param>
        /// <param name="helpFile"> The help file. </param>
        /// <param name="monitorName"> The monitor name. </param>
        /// <param name="defaultDataType"> The default data type. </param>
        /// <exception cref="Win32Exception">Raised when the operation errored for whatever reason</exception>
        public void AddPrintDriver(
            string configFile,
            string dataFile,
            string[] dependentFiles,
            string driverPath,
            string driverName,
            string environment,
            string helpFile        = null,
            string monitorName     = null,
            string defaultDataType = "RAW")
        {
            // DRIVER_INFO_6 structure type
            const int DriverInfoVersion6 = 6;

            // Create the full path to the print directory where these files *should* be installed to (we will find out
            // if that is the case when attempting to add the driver as the call will fail
            string printDirectory = GetPrinterDriverDirectory(environment);

            Logger.Info("Print directory is " + printDirectory);

            Func <string, string> installedPath = fileName => Path.Combine(printDirectory, fileName);

            var di6 = new SafeNativeMethods.DRIVER_INFO_6();

            di6.cVersion         = 3;
            di6.pName            = driverName;
            di6.pConfigFile      = installedPath(configFile);
            di6.pDataFile        = installedPath(dataFile);
            di6.pDependentFiles  = dependentFiles.Length == 1 ? installedPath(dependentFiles[0]) : null;
            di6.pDriverPath      = installedPath(driverPath);
            di6.pEnvironment     = environment;
            di6.pHelpFile        = installedPath(helpFile);
            di6.pMonitorName     = monitorName;
            di6.pDefaultDataType = defaultDataType;

            int tryCount = 1;

            while (true)
            {
                try
                {
                    IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SafeNativeMethods.DRIVER_INFO_6)));

                    try
                    {
                        Marshal.StructureToPtr(di6, intPtr, false);

                        if (!SafeNativeMethods.AddPrinterDriverExW(
                                null,
                                DriverInfoVersion6,
                                intPtr,
                                SafeNativeMethods.APD_COPY_NEW_FILES))
                        {
                            int w32Error = Marshal.GetLastWin32Error();
                            throw new Win32Exception(w32Error);
                        }

                        Logger.Info("Print driver installed successfully with name of " + driverName + " after " + tryCount + " attempts");
                        break;
                    }
                    finally
                    {
                        if (IntPtr.Zero != intPtr)
                        {
                            Marshal.FreeHGlobal(intPtr);
                        }
                    }
                }
                catch (Win32Exception win32Ex)
                {
                    // YUCK - on some machines, driver registration will fail the first time it is called (when run as an administrator).
                    // This retry loop is added to try and force the issue to see if it is a timing problem (simulates several attempts by the
                    // user to register the driver).
                    Logger.Warn("Error caught trying to create print driver : " + win32Ex);
                    Thread.Sleep(AddPrintDriverRetryInterval);

                    if (tryCount > AddPrintDriverRetryLimit)
                    {
                        Logger.Fatal("Retry count exceeded, unable to create print driver");
                        throw;
                    }

                    tryCount++;
                }
            }
        }