So, I know this is atrocious, but can I expect to get the Acrobat FDF Toolkit, for which the latest documentation I can find was released in October 2003, to work on Windows Server 2016?
From the SysWOW64 directory, I have run regsvr32 for the binary, which I have placed in it's own directory in the root of the C drive. It indicated success, and I can see evidence of that in the registry. However, when I try to navigate to a simple ASP Classic page that utilizes this library, it fails on this line:
Set FdfAcX = Server.CreateObject("FdfApp.FdfApp")
with the error message:
Microsoft VBScript runtime error '800a01ad'
ActiveX component can't create object
This page claims this error is induced when the IUSR_computer and IWAM_computer do not have read permissions to the directory of the binary. I believe I have provided those accounts that permission (though the only ones I could find in my case are IUSR_domain and IWAM_domain... ?), but the error persists.
What steps do I need to take to resolve this error?
If you are only filling in fields on a pdf template, you can do it without creating an object. You can do by just kind of filling out the form.
TheFdfPdf.asp: The variables within the parenthesis are names of your fields on your pdf form.
<%
Response.ContentType = "application/vnd.fdf"
PdfTemplateUrl = "http://TheDomain.com/pdfs/ThePdf.pdf"
SomeTextValue = "This is a test value for some field on a pdf form"
SomeNumber = 789
SomOtherValue = "Groovy"
%>
%FDF-1.2
1 0 obj
<<
/FDF
<<
/Fields [
<< /T (SomeTextValue) /V (<%=SomeTextValue%>) >>
<< /T (SomeNumber) /V (<%=SomeNumber%>) >>
<< /T (SomOtherValue) /V (<%=SomOtherValue%>) >>
]
/F (<%=PdfTemplateUrl%>) >>
>>
endobj
trailer
<< /Root 1 0 R >>
%%EOF
Related
BUMP: any thoughts or suggestions?
Building my web application has been throwing the following errors:
The command ""C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /a /t http://timestamp.verisign.com/scripts/timestamp.dll "application.exe"" exited with code 1
An error occurred while attempting to sign: application.exe
The specified timestamp server either could not be reach or
Based on this post, I added different servers with something like
signtool sign /v /td sha256 /tr "http://timestamp.comodoca.com/rfc3161" /fd sha1 application.exe
but my build still references the Verisign URL even after running this signtool catdb /r http://timestamp.verisign.com/scripts/timestamp.dll and signtool remove http://timestamp.verisign.com/scripts/timestamp.dll
Any ideas? Do I need to create a new certificate? Thanks in advance for help!
So I finally found what the problem was. There was a Build Event setting this reference to Verisign. Once I found it and updated, the build was successful.
The location of this is r-click on the project < select Properties < select the Compile tab < click button for Build Events...
Hope this helps any others.
I'm trying to get familiar with the robotframework using autoitlibrary to test Windows applications. I found some examples which use the Send command to type text into a notpad window.
That's what I've done so far:
*** Settings ***
Library AutoItLibrary
*** Variables ***
${app} C:/Program Files/Notepad++/notepad++.exe
*** Test Cases ***
Enter text
Run ${app}
Win Wait Active new 1 - Notepad++
Send This is just a test.
So, the Notepad++ window is opened, but then it failed with the No keyword with name 'Send' found. message. I suppose there is no Send command in the AutoItLibrary, but I also cannot find any other command which may do this job.
AutoIt is installed, and so is the wrapper by pip install robotframework-autoitlibrary.
There really exists a Send keyword in AutoIt, but supposedly not in the wrapper for robotframework.
And ideas to fix this?
UPDATE: Windows 10 (64bit in a VirtualBox), Python v3.7.6 (32bit), RF v3.1.2, RF-AutoItLibrary v1.2.4, AutoIt v3.3.14.5
The "Search Keywords" dialog in RIDE provides AutoItLibrary as a Source, but then list only a few commands. So I suppose the library is accessible, but incomplete.
import os, re, subprocess, sys
# Set path to Python directories.
programfiles = os.environ['programfiles']
if not programfiles:
exit('Failed to get programfiles')
python_dirs = [os.path.join(programfiles, 'Python35'),
os.path.join(programfiles, 'Python36'),
os.path.join(programfiles, 'Python37'),
os.path.join(programfiles, 'Python38')]
# Process each python directory.
for python_dir in python_dirs:
print('---')
# Set path to AutoItX3.dll.
autoitx_dll = os.path.join(python_dir, r'Lib\site-packages\AutoItLibrary\lib\AutoItX3.dll')
if not os.path.isfile(autoitx_dll):
print('File not found: "' + autoitx_dll + '"')
continue
# Set path to the makepy module.
makepy = os.path.join(python_dir, r'Lib\site-packages\win32com\client\makepy.py')
if not os.path.isfile(makepy):
print('File not found: "' + makepy + '"')
continue
# Generate cache using make.py.
command = [os.path.join(python_dir, 'python.exe'), makepy, autoitx_dll]
with subprocess.Popen(command, stderr=subprocess.PIPE, cwd=python_dir, universal_newlines=True) as p:
stderr = p.communicate()[1]
print(stderr.rstrip())
parameters = re.findall(r'^Generating to .+\\([A-F0-9\-]+)x(\d+)x(\d+)x(\d+)\.py$', stderr, re.M)
if len(parameters) == 1:
parameters = parameters[0]
print('Insert the next line into AutoItLibrary.__init__.py if not exist.\n'
' win32com.client.gencache.EnsureModule("{{{guid}}}", {major}, {minor}, {lcid})'
.format(guid=parameters[0],
major=parameters[1],
minor=parameters[2],
lcid=parameters[3]))
# Pause so the user can view the subprocess output.
input('Press the return key to continue...')
The generated cache done by win32com\client\makepy.py for AutoItLibrary from the setup.py is saved in the %temp%\gen_py folder. This is done only when setup.py is executed. If the %temp% directory is cleaned later, which removes the cache, then I notice keywords like Send may fail to be recognized by the robotframework.
One solution appears to be regenerating the cache. The code above will generate the cache by use of makepy.py. It may also print a message about inserting win32com.client.gencache.EnsureModule(...) into AutoItLibrary\__init__.py for any of the Python versions as needed. This will ensure the cache is available when AutoItLibrary
is imported.
Change paths in the code to suit your environment.
With further research:
AutoItLibrary currently has AutoItX 3.3.6.1 and latest AutoIt has AutoItX 3.3.14.5. Important to know as one version registered can overwrite the registration of the previous registration.
AutoItLibrary currently registers AutoIt3X.dll without the _x64 suffix on the name on x64 systems. I may reference AutoIt3_x64.dll to define difference between x86 and x64.
Any version of AutoIt3X.dll and AutoIt3_x64.dll uses the same ID codes and the last registered wins (based on bitness as both x86 and x64 registrations can co-exist).
The TypeLib class key registered ID is {F8937E53-D444-4E71-9275-35B64210CC3B} and is where win32com may search.
If AutoIt3X.dll and AutoIt3_x64.dll are registered, unregister any 1 of those 2 will remove the AutoItX3.Control class key. Without this key, AutoIt3X will fail as AutoItLibrary needs this key. To fix, register again e.g. regsvr32.exe AutoIt3X.dll as admin in the working directory of AutoIt3X.dll.
The methods of any same version of AutoItX will match i.e. AutoIt3X.dll and AutoIt3X_x64.dll only changes in bitness, not methods.
Inserting win32com.client.gencache.EnsureModule("{F8937E53-D444-4E71-9275-35B64210CC3B}", 0, 1, 0) into AutoItLibrary\__init__.py should ensure the cache is always available for any AutoItX version. The initial code can be used to generate the cache, though the suggested change in AutoItLibrary\__init__.py makes it obsolete as the cache is generated on import of AutoItLibrary. If the ID was not constant, then the initial code may inform you of the ID to use.
The cache is important as it has generated .py files with methods like e.g.:
def Send(self, strSendText=defaultNamedNotOptArg, nMode=0):
'method Send'
# etc...
which if missing, makes Send and many others, an invalid keyword in AutoItLibrary.
If AutoItX 3.3.14.5 is registered, the - leading methods are removed and the + leading methods are added as compared to AutoItX 3.3.6.1:
-BlockInput
-CDTray
-IniDelete
-IniRead
-IniWrite
-RegDeleteKey
-RegDeleteVal
-RegEnumKey
-RegEnumVal
-RegRead
-RegWrite
-RunAsSet
+RunAs
+RunAsWait
So if any of those methods causes error, then you may want AutoItX 3.3.6.1 registered instead. In the AutoItX history, 3.3.10.0 release is when those method changes happened.
Fix:
Check your python architecture ( is it 32 or 64 bit)
For 32:
Open cmd in "Run as administrator" mode
run the command pip install robotframework-autoitlibrary
Now clone the autoit library source code:
https://github.com/nokia/robotframework-autoitlibrary
in the root directory run the below command: python setup.py install using cmd in admin mode
to navigate to root directory use the command pushd <filepath>' instead ofcd ` if cd doesn't work in cmd opened in admin mode.
For 64:
Open cmd in "Run as administrator" mode
Now clone the autoit library source code:
https://github.com/nokia/robotframework-autoitlibrary
in the root directory run the below command: python setup.py install using cmd in admin mode
to navigate to root directory use the command pushd <filepath>' instead ofcd ` if cd doesn't work in cmd opened in admin mode.
I'm opening dumpfile in Windbg, and I'm writing a PYKD related Python script for working with that dumpfile. Now I'd like to create a file in the directory of that dumpfile, and the name of that file should be based on the dumpfile I've just opened.
In order to do this, I'd simply need to know the path of the dumpfile I've opened, but I don't find the basic Windbg command nor the PYKD command to get this.
How can I get the path of the file, I've opened in Windbg?
I don't know a specific PyKD command, but you could always use dbgCommand() and then use a WinDbg command.
|| should give you the needed information:
0: kd> ||
. 0 64-bit Kernel triage dump: F:\some\path\test.dmp
Please note that || shows the system status and may have multiple lines if you're debugging multiple systems at once:
||1:1:012> ||
0 64-bit Kernel triage dump: F:\some\path\test.dmp
. 1 Live user mode: <Local>
It's likely not applicable in your case.
>>> targetSystem().desc
u'64-bit Kernel bitmap dump: C:\\Users\\User\\AppData\\Local\\Temp\\000030a40_memory.dmp'
desc returns the same string as ||
This is as much a note for myself as to help anyone else.
We migrated a Classic ASP application to Window 2016. Everything worked in the end. Then an issue surfaced with some zip & download functionality for which we use a Zip component from Chilkat.
Initially, all looked well - the software component was installed and responded to instantiation, but the zip files did not appear on disk where expected.
What could it be? Modifying the code as:
Set oZip = Server.CreateObject(CHILLKAT_ZIP_OBJECT_NAME)
oZip.UnlockComponent(<the license code>)
oZip.WriteZipAndClose()
Response.Write "<pre>" & Server.HTMLEncode( ozip.LastErrorText) & "</pre>"'
response.end
Produced
ChilkatLog:
WriteZipAndClose:
DllDate: Mar 1 2011
UnlockPrefix: *******
Username: *******
Architecture: Little Endian; 32-bit
Language: ActiveX
tempFile: .\ckz_40NT.tmp
Encryption: 0
PasswordProtected: 0
Failed to open file (2)
filename: .\ckz_40NT.tmp
currentWorkingDirectory: C:\Windows\SysWoW64\inetsrv
osErrorInfo: Access is denied.
Filename: .\ckz_40NT.tmp
Failed to open output Zip file
zipFilename: .\ckz_40NT.tmp
Retrying with a new temp filename
Encryption: 0
PasswordProtected: 0
Failed to open file (2)
filename: .\ckz2_I473.tmp
currentWorkingDirectory: C:\Windows\SysWoW64\inetsrv
osErrorInfo: Access is denied.
Filename: .\ckz2_I473.tmp
Failed to open output Zip file
zipFilename: .\ckz2_I473.tmp
tempFileName: .\ckz2_I473.tmp
Cannot open temporary file
Failed.
What could the prolem be ?
The issue was with chilkat's tempdir setting. On our version of Chilkat Tempdir defaulted to the IIS home folder which is unlikely ever to be happy having random files written to it. Adding a line to set tempdir to something more sensible, as below, cured the issue.
Set oZip = Server.CreateObject(CHILLKAT_ZIP_OBJECT_NAME)
oZip.UnlockComponent(<the license code>)
' added the next line !
oZip.TempDir = Server.MapPath("/some accessible folder path")
oZip.WriteZipAndClose()
Response.Write "<pre>" & Server.HTMLEncode( ozip.LastErrorText) & "</pre>"'
Useful info. I'm a Classic ASP programmer and at some point will need to move from Windows 2012 to Windows 2016. Been putting it off!
I need some Powershell advice.
I need to install an application's MSP update file on multiple Win08r2 servers. If I run these commands locally, within the target machine's PS window, it does exactly what I want it to:
$command = 'msiexec.exe /p "c:\test\My Application Update 01.msp" REBOOTPROMPT=S /qb!'
invoke-wmimethod -path win32_process -name create -argumentlist $command
The file being executed is located on the target machine
If I remotely connect to the machine, and execute the two commands, it opens two x64 msiexec.exe process, and one msiexec.exe *32 process, and just sits there.
If I restart the server, it doesn't show that the update was installed, so I don't think it's a timing thing.
I've tried creating and remotely executing a PS1 file with the two lines, but that seems to do the same thing.
If anyone has advice on getting my MSP update installed remotely, I'd be all ears.
I think I've included all the information I have, but if something is missing, please ask questions, and I'll fill in any blanks.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
My process for this is:
Read a CSV for server name and Administrator password
Create a credential with the password
Create a new session using the machine name and credential
Create a temporary folder to hold my update MSP file
Call a PS1 file that downloads the update file to the target server
>>> Creates a new System.Net.WebClient object
>>> Uses that web client object to download from the source to the location on the target server
Call another PS1 file that applies the patch that was just downloaded –>> This is where I’m having issues.
>>> Set the variable shown above
>>> Execute the file specified in the variable
Close the session to the target server
Move to the next server in the CSV…
If I open a PS window and manually set the variable, then execute it (as shown above in the two lines of code), it works fine. If I create a PS1 file on the target server, containing the same two lines of code, then right click > ‘Run With PowerShell’ it works as expected / desired. If I remotely execute my code in PowerGUI, it returns a block of text that looks like this, then just sits there. RDP’d into the server, the installer never launches. My understanding of the “Return Value” value is that “0″ means the command was successful.
PSComputerName : xx.xx.xx.xx
RunspaceId : bf6f4a39-2338-4996-b75b-bjf5ef01ecaa
PSShowComputerName : True
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 4808
ReturnValue : 0
I even added a line of code between the variable and the execution that creates a text file on the desktop, just to verify I was getting into my ‘executeFile’ file, and that text file does get created. It seems that it’s just not remotely executing my MSP.
Thank you in advance for your assistance!
Catt11.
Here's the strategy I used to embed an msp into a powershell script. It works perfectly for me.
$file = "z:\software\AcrobatUpdate.msp"
$silentArgs = "/passive"
$additionalInstallArgs = ""
Write-Debug "Running msiexec.exe /update $file $silentArgs"
$msiArgs = "/update `"$file`""
$msiArgs = "$msiArgs $silentArgs $additionalInstallArgs"
Start-Process -FilePath msiexec -ArgumentList $msiArgs -Wait
You probably don't need to use the variables if you don't want to, you could hardcode the values. I have this set up as a function to which I pass those arguments, but if this is more of a one-shot deal, it might be easier to hard-code the values.
Hope that helps!
using Start-Process for MSP package is not a good practice because some update package lockdown powershell libs and so you must use WMI call