Jump to content
jguinch

Printers Management UDF

Recommended Posts

UEZ

Thanks for sharing. Might be useful someday.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
czyt

Thanks,guy!It's useful for me!


董小姐,你微笑的时候很美,就像安河桥下,清澈的水...

Share this post


Link to post
Share on other sites
Vincor

Can be very useful here too. Once in a while I try to automate something with print queues and ports. I will have it a go in a few days.

Thanks jguinch

Share this post


Link to post
Share on other sites
benched42

I just came across this UDF and it looks very promising. I'd like to have some documentation on it. For instance, when adding a printer to a computer and I know the driver is not present on the machine, do I use the _AddPrinter or do I use the _AddPrinterDriver followed by the _AddPrinter? Do I need to install the driver first? If so, why is the final parameter only limited to the OS options of Win9x, Win351, NT40 and Win2k?

I'm trying to automate adding printers in various locations that do not have servers. All the clients are 64-bit Windows 7 and all printers will be direct TCP/IP port printing to a Canon imageRUNNER (various models).


Who lied and told you life would EVER be fair?

Share this post


Link to post
Share on other sites
jguinch

Thank you for your interest.

Yes, you must install the driver first (with _AddPrinterDriver).

The default value for $sVersion parameter is 3 : it seems Windows 2000 and upper (in your case, I think). You will rarely have to install an old driver on a recent System... So you can use the default value.

For the $sDriverPlatform value, the values can be Windows NT x86 or Windows x64. (depending of the type of driver that you want to install).



 

Share this post


Link to post
Share on other sites
Biatu

I made a script to get a list of all printers then remove them all. which works for the most part, but some printers are not removed and get greyed out with a yellow triangle on their icon. the property page is blank.


What is what? What is what.

Share this post


Link to post
Share on other sites
Biatu

Biatu : what type are printers that have not been removed ? Shared ?

In _RemovePrinter, you must use serverprinterShare for shared printers.

 

Nope, they are not shared, or network printers. they are connected via USB port. I test various printers, and the printer list gets pretty full so I run the script.

The issue used to be printer jobs from other users, so i made a func to remove all jobs from all printers.

Then another dell status service was locking some printers (afaik) so i stop the service.

that didnt work completely,so now I restart the spooler service, which remove most. all except for the "Dell 5330 Mono Laser MFP"

The env is win7 enterprise x64.

Edited by Biatu

What is what? What is what.

Share this post


Link to post
Share on other sites
Biatu

_AddPrinter is not working either, i keep getting error dialog...

Error Number: -2147352567

WinDescription: Exception occurred.

Description: Generic Failure

Source: $WbemObjectEx

#Include <Printers.au3>

$Name="PrintNet.1"
$Driver="Dell 2335dn MFP,3,Windows x64"
$File="C:\Test1.pcl";@ScriptDir&"\"&$Name&".pcl"
_AddPrinter($Name,$Driver,"C:\Test1.pcl")

Thanks


What is what? What is what.

Share this post


Link to post
Share on other sites
glakra

Hello Guys,

 

I am new to autoit. I want  to run a program called PrinterInfo.exe, search for the the specific word " STATUS_PAPEROUT", if found then send email to desired recipient.

So far I have only able to run program, take a window capture save the window capture and then email the window capture to the recipient. But this is not what i want.

 

I have read posts which suggest that I should use WinGetText to retrieve the word, however I have still no idea as to how to search for the specific word " STATUS_PAPEROUT" and if present then send email.

 

Please help

Share this post


Link to post
Share on other sites
Biatu

I use this to determine the printer type:

http://<Printer IP>:5200/Printer.xml

then i use the printer's network interface for everything else.

Currently i am doing research with PCL, SNMP, etc.

Edited by Biatu

What is what? What is what.

Share this post


Link to post
Share on other sites
jguinch

Biatu, you have to install the driver before installing the printer : it could be done with _AddPrinterDriver (look at the example above).

Next, you have to know the port on which you want to install the printer (if needed, create a network port with _AddTCPIPPrinterPort.

And finally, you can add the printer...

I just downlod the Dell 2335dn MFP driver, so the installation can be done like this :

#Include "printers.au3"

Local $sPrinterName = "My Dell 2335dn Printer"
Local $sDriverName = "Dell 2335dn MFP"
Local $sPortIP = "192.168.1.250"
Local $sPortName = "IP_192.168.1.250"
Local $iPortnumber = 9100

_AddPrinterDriver($sDriverName, "Windows x64", @ScriptDir & "\Printer\PCL\WINXP_VISTA_64\", @ScriptDir & "\Printer\PCL\WINXP_VISTA_64\sdf1m.INF")
_AddTCPIPPrinterPort($sPortName, $sPortIP, $iPortnumber)
_AddPrinter($sPrinterName, $sDriverName, $sPortName)

Share this post


Link to post
Share on other sites
Biatu

Thank you jguinch, will check out func on monday.


What is what? What is what.

Share this post


Link to post
Share on other sites
Biatu

If I remove a printer using your func will I still need to remove port, or is that auto?

Thanks


What is what? What is what.

Share this post


Link to post
Share on other sites
Biatu

_RemovePrinter does not remove the port. You must do it after.

Same thing for the driver.

Tried that, gives error. So i left it out, and the port does not show up on ports list when new printer is added or on the existing ones. So i assume that it's removed automatically


What is what? What is what.

Share this post


Link to post
Share on other sites
ViciousXUSMC

Hmm, is this a global (all users) add/delete of local (current profile)?

Speaking exclusively of printserver printers that normally only add per user, unlike local printesr that default to all users. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I'm working on a little project of mines, and I was trying to use WMI Object.
      The question which I don't find an answer is: 
      Once I do the query with WMI Object, something like "SELECT * FROM Win32_LogonSession", instead of specify the field of the collection returned, ( i.e. $colItems.Caption ), can I loop though each property and each value of the property, writing so one row of code only?
      Hope my question was clear enough.
      Thanks in advance.

      Best Regards.
    • ahmet
      By ahmet
      Hello,
      I am trying to make a program that will uninstall some software, provided by some form of a list. I have this
      ; Generated by AutoIt Scriptomatic June 08, 2010 ;#RequireAdmin $sPartialName="java" $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" ;$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") ;$objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Product", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) then For $objItem In $colItems If StringInStr($objItem.Name,$sPartialName)=1 Then ConsoleWrite("Full name:" & $objItem.Name & @CRLF) RunAs("USERNAME",@ComputerName,"PASSWORD",0,@ComSpec & " /c" & ' wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"C:\WINDOWS\system32\wbem",@SW_MAXIMIZE) ;Run('wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"",@SW_MAXIMIZE) ExitLoop EndIf Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Product" ) Endif The script above fails uninstalling software despite providing username and password for admin account. If I run script with admin rights then the software gets uninstalled.
      At the following link there is a script by JLogan3o13 but it does not either uninstall software, unless run as admin..
      Is there some way to uninstall software using wim or wimc by providing user name and password?
       
    • Bilgus
      By Bilgus
      #include <Array.Au3> ;WMI EXAMPLE Local $strComputer = "localhost" Local $sClass = "" Local $objClass Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2") ; Display all available Classes in this object _ArrayDisplay(Get_Classes($objWMIService), "AVAILABLE WMI CLASSES", "", 0, Default, "NAME") ;Split string at \n(@LF) place each into an array $sClass = "Win32_BIOS" ;<-The Class I've choosen ;Lets Try out one of the classes Local $objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass) ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF) _ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE") ;No methods available for this one but... ConsoleWrite("Methods:" & @CRLF & @CRLF) Get_Methods($objClass) ;Lets Do it again for the network adapter Class $sProperties = "" $sClass = "Win32_NetworkAdapterConfiguration" ;<-The Class I've choosen ;Lets Try out one of the classes $objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass) ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF) _ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE") ConsoleWrite("Methods:" & @CRLF & @CRLF) Get_Methods($objClass) Func Get_Classes($obj) ; Display all available Classes in this object If IsObj($obj) Then Local $sClasses = "" For $objClass In $obj.SubclassesOf() ;<--WMI Method $sClasses &= ($objClass.Path_.Class) & @LF ;Build a string seperated by \n(@LF) Next EndIf Return StringSplit($sClasses, @LF) EndFunc ;==>Get_Classes Func Get_Methods($objClass) Local $sResults = "" If IsObj($objClass) Then For $objMethods In $objClass.Methods_ ConsoleWrite(@TAB & $objMethods.Name & @CRLF) $sResults &= $objMethods.Name & @LF Next EndIf Return $sResults EndFunc ;==>Get_Methods Func Get_Properties($objClass) Local $sProperties = "" If IsObj($objClass) Then For $objClassProp In $objClass.Properties_() ;<-Another WMI Method For $obj In $objWMIService.ExecQuery("Select * from " & $sClass) ;<-Another WMI Method $sProperties &= $objClassProp.Name & @CR $sProperties &= Parse_Value($obj.Properties_($objClassProp.Name).Value) ;Use the Properties_ Method to call our desired property Next Next EndIf Return $sProperties EndFunc ;==>Get_Properties Func Parse_Value($vValue) Local $sRet = "" Switch StringLower(VarGetType($vValue)) Case "keyword" ; Not really sure what this one is probably NULL $sRet = Number($vValue) = 0 ? "" : Number($vValue) Case "array" $sRet = _ArrayToString($vValue, ", ") Case "string", "bool", "int32", "int64", "double", "binary" $sRet = $vValue Case "pointer" $sRet = "[PTR]:" & $vValue Case Else $sRet = "[" & VarGetType($vValue) & "]: " & $vValue EndSwitch $sRet &= @LF Return $sRet EndFunc ;==>Parse_Value Func Split_Properties($sProperties) Local $aDisp = StringSplit($sProperties, @LF) ;Split string at \n(@LF) place each into an array Local $aTmp If IsArray($aDisp) Then _ArrayColInsert($aDisp, 1) For $i = 1 To $aDisp[0][0] ; String Split stores Count in the first element by default $aTmp = StringSplit($aDisp[$i][0], @CR) ;Split string at \r(@CR) place each into an array If IsArray($aTmp) Then $aDisp[$i][0] = $aTmp[0] > 0 ? $aTmp[1] : "?" ;Check if this element exists if not make it "?" $aDisp[$i][1] = $aTmp[0] > 1 ? $aTmp[2] : " " ;Check if this element exists if not make it " " EndIf Next EndIf Return $aDisp EndFunc ;==>Split_Properties  
    • nikink
      By nikink
      Hi all,
      I have a bit of code that works on my old Win10 PC, that fails on my new Win10 PC, and I think the only significant difference is the version of Autoit - old PC has 3.3.12, new has 3.3.14.
      I couldn't find anything mentioned in the change logs though, so perhaps I'm wrong.
      Anyway, the code to replicate my issue is:
      Test('username', 'DOMAIN') ; THIS ERRORS: ;Test('localun', 'DOMAIN') ; THIS ERRORS: ;Test(' ', ' ') ; THIS ERRORS: ;Test('', '') ; THIS ERRORS: ;Test('localun', '') ; THIS ERRORS: ;Test('', 'DOMAIN') Func Test($un, $dom) $compName = 'PCNAME' $FullName = '.' $Description = '.' ; get the WIM object $objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2") ; get default user full name and description $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") If IsObj($objAccount) Then $FullName = $objAccount.FullName $Description = $objAccount.Description EndIf ConsoleWrite($FullName & @CRLF) ConsoleWrite($Description & @CRLF) Return EndFunc  
      On my old PC this code will output just . and . for each of those line currently commented out. Which is fine.
      On my new PC any of those commented out lines of code cause an error, and the script won't even compile.
      $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") $objAccount = $objWMIService^ ERROR I'm very much a newb with the WMI stuff and objects, but it looks like the .Get property is failing when either $un or $dom aren't valid in v3.3.14, whereas in 3.3.12 the .Get would fail to return an object, which is then caught by the If statement.
      Am I on track with this? Is there some new/better way to code the example so that 3.3.14 will compile it?
    • willichan
      By willichan
      So, this is not one of my neatest scripts, but I haven't contributed much to the forum lately, and this was a help to me this week.
      I was migrating about 40 print queues from an old print server to a new one.  Since this entails removing the old printer and creating the new printer for each user on each PC for each print queue used (for about 350 users), doing this manually was out of the question.
      I just added this to the logon scripts to run once per user per machine.
      If anyone finds the need to make a similar migration, please feel free to use/modify this.
      Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ;don't want to crash out if there is a problem. #include "PrintMgr.au3" ;https://www.autoitscript.com/forum/topic/155485-printers-management-udf/ #include "ServiceControl.au3" ;https://www.autoitscript.com/forum/topic/6487-updated-service-control-funtions/ #include <array.au3> Global $sOldPrintServer = "oldservername" Global $sNewPrintServer = "newservername" Global $sDefaultPrinter = _CleanName(_GetDefaultPrinter()) ;If you change print queue names below, you may need to take that into account and modify $sDefaultPrinter as well. Global $aPrinters = _PrintMgr_EnumPrinter() If @error Then Exit Global $aReplaced[1] = [0] Global $sTempName ;remove printers that are mapped to old server For $iLoop = 1 To $aPrinters[0] If Not StringInStr($aPrinters[$iLoop], $sOldPrintServer) Then ContinueLoop ;not a printer we are concerned with $sTempName = $aPrinters[$iLoop] ConsoleWrite("Removing " & $sTempName & @CRLF) _PrintMgr_RemovePrinter($sTempName) $sTempName = _CleanName($sTempName) ;If you need to change a print queue name, modify $sTempName here before adding it to the array. _ArrayAdd($aReplaced, $sTempName) $aReplaced[0] = $aReplaced[0] + 1 Next ;Stop and re-start print spooler. This alleviated problems on a few machines. ConsoleWrite("Stopping Spooler" & @CRLF) _StopService(@ComputerName, "spooler") Sleep(1000) ConsoleWrite("Starting Spooler" & @CRLF) _StartService(@ComputerName, "spooler") Sleep(1000) ;remap to the new server (assuming all of the print queues have the same share name) For $iLoop = 1 To $aReplaced[0] Local $isdefault = False If $aReplaced[$iLoop] = $sDefaultPrinter Then $isdefault = True ConsoleWrite("Adding \\" & $sNewPrintServer & "\" & $aReplaced[$iLoop] & "(" & $isdefault & ")" & @CRLF) _PrintMgr_AddWindowsPrinterConnection("\\" & $sNewPrintServer & "\" & $aReplaced[$iLoop]) If $isdefault Then _PrintMgr_SetDefaultPrinter("\\" & $sNewPrintServer & "\" & $aReplaced[$iLoop]) Next Func _GetDefaultPrinter() ; CyberSlug - 18 Nov 2004 Local $key, $default, $defPrtNm If @OSType = "WIN32_WINDOWS" Then $key = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Printers" $defPrtNm = RegRead("HKEY_CURRENT_CONFIG\System\CurrentControlSet\Control\Print\Printers", "Default") Else ;WIN_NT type $key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers" $default = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device") $defPrtNm = StringLeft($default, StringInStr($default, ",") - 1) EndIf Return $defPrtNm EndFunc ;==>_GetDefaultPrinter Func _CleanName($sName) Local $sTempName = $sName $sTempName = StringReplace($sTempName, "\\" & $sOldPrintServer & "\", "") Return $sTempName EndFunc ;==>_CleanName Func MyErrFunc() ;just dump the info to the console and keep going Local $sErrNum Local $sMsg $sErrNum = Hex($oMyError.Number, 8) $sMsg = "Error Number: " & $sErrNum & @CRLF $sMsg &= "WinDescription: " & $oMyError.WinDescription & @CRLF $sMsg &= "Script Line: " & $oMyError.ScriptLine & @CRLF ConsoleWrite($sMsg) EndFunc ;==>MyErrFunc  
×