I want to modify a word document from an agent in Lotus Script. Domino server starts as a service with an Administrator user count. The word document is attached in a Lotus Notes document. I extract the document in a folder that Domino has access.
When the Domino server (as service) runs the process, the Domino displays an error. But when I start the Domino server as application, the process runs well and it doesn't get any error.
The script code is the next:
Set rtItem = doc_perfil.GetFirstItem(campo)
Set obj = rtitem.EmbeddedObjects(0)
sFile = RUTA + "\" + ReplaceSubstring(nameNewFile, "/", "-") + ".docx"
Call obj.ExtractFile(sFile)
OLE_OBJECT = "word.application"
Set Word = CreateObject (OLE_OBJECT)
Set templt = Word.Documents.Add (sFile)
The line that produces the error is "Set templt = Word.Documents.Add (sFile)"
As a first point, running Word on a server is totally unsupported by Microsoft.
The quick and dirty way round this is to not run Domino as a service. A service can't interact with the UI which it needs to for OLE.
The downside to this is that the Domino Server will need to be manually restarted if the Windows server ever reboots.
The proper way to do this is to do what you need in java using a library like docx4j or Apache POI. As you don't include any code beyond opening the word doc, I can't comment further on what would be a suitable library.
In the line of code,
Set templt = Word.Documents.Add (sFile)
Add, does not take parameters, please try word.documents.open
If the Domino is not run as a service and still the error occurs, change the security level of the agent to 3 (run will full admin rights)
Related
I have a classic asp page in VBS and I am trying to create a file on the web server with the following code.
Set fso = CreateObject("Scripting.FileSystemObject")
Set file1 = fso.CreateTextFile("\\localhost\inetpub\wwwroot\cs\batch\123456dirs.bat", true)
This returns the following error:
|666|800a0034|Bad_file_name_or_number
Line 666 is the CreateTextFile line.
According to the Microsoft docs, this means that I'm trying to create a file with an invalid filename. Then it explains the rules for filenames and mine appears to be perfectly valid.
Any suggestions or ideas on how I can further troubleshoot this?
first thing to check to make sure your users have access to the folder. Assuming you're not using windows authentication, make sure IUSR account has write access to the folder.
second, unless inetpub is set up as a share to folder, you're syntax won't work. if the root of your website is located in the CS folder, you can do something like:
Set file1 = fso.CreateTextFile(Server.MapPath( "/cs/batch/123456dirs.bat" ), true)
The createtextfile() function runs on the web server but in the context of the local server itself. Simply put, any path you give it must resolve as if you were logged on to a windows desktop on the server and tried to CD to that path.
The format \localhost... is a UNC path. See this question for a discussion about UNC paths and windows. Unless you know for sure that there is a UNC path mapped for \localhost then that is probably your issue. You may be making the assumption the \localhost will be a reasonable path to use, but as I said unless you know for sure it is available then this is an invalid choice.
Lastly, if you decide to set up a share for \localhost, you will be getting in to some interesting territory around the user context that the web server operates in. You see you will have to set up the share for the IIS user that is configured as the run-as identity for IIS, so you will need to know that and create the required config to give that user the share.
If it were me, I would switch to using a standard windows path, although even then you need to appreciate the run-as user context and security config, etc.
I've been experimenting a bit with CodeKit and I wanted to insure that my changes were auto-uploading to my web server.
To solve this, I have written an AppleScript recently that waits until files are processed and then runs on the entire project directory.
The problem I'm having is that my script keeps opening up new "windows". Ideally, I'd like to never have more than a single window open at one time, so I thought I could have the script close the new document that's created. However, I'm struggling with the syntax.
Here is my code:
tell application "Transmit"
set myFave to item 1 of (favorites whose name is "Favorite Name")
set myRules to (skip rules whose enabled is true)
tell current tab of (make new document at end)
connect to myFave
change location of local browser to path ""
change location of remote browser to path ""
synchronize local browser to remote browser using skip rules myRules
close remote browser
end tell
end tell
So my question(s) are:
Is there a better/more efficient way to do what I'm trying to do?
If I'm on track, how can I set that new document being created to close once the script is done running?
I ended up answering my own question!
The answer was surprisingly simple. I noticed in the AppleScript dictionary for Transmit that there was a "close" method which relates to documents (which was the thing I was trying to close).
I was puzzled at first because I thought I'd need to specify what I was closing. But ultimately, I just added "close" after "close remote browser".
tell application "Transmit"
set myFave to item 1 of (favorites whose name is "TitanHost")
set myRules to (skip rules whose enabled is true)
tell current tab of (make new document at end)
connect to myFave
change location of local browser to path ""
change location of remote browser to path ""
synchronize local browser to remote browser using skip rules myRules
close remote browser
close
end tell
end tell
I hope this helps someone else!
Like so many of you at the moment I am moving a legacy classic ASP application from a Windows 2003 server to Windows 2008. I have this mostly working but I am unable to send e-mail through it. This is because CDOSYS is not configured correctly. Despite about 4-5 hours' googling and running through API documentation and even searching through all files on the filesystem and the system registry I was unable to figure out where this is set.
The ASP.NET portion of the legacy application works fine. It is able to send e-mails to localhost without authentication which are then passed through to the mail server with authentication for sending to their destination.
I translated the VB6 calls from the source code into a Powershell script for convenience:
$config = new-object -com "CDO.Configuration";
$config.Load(1);
$smtp = new-object -com "CDO.Message";
$smtp.Configuration = $config;
$smtp.From = "me#example.com"
$smtp.To = "me#example.com"
$smtp.Subject = "test"
$smtp.TextBody = "Message";
$smtp.Send();
This script sends an e-mail correctly on my original server. On the new server it returns this error when calling $smtp.Send():
Exception calling "Send" with "0" argument(s): "The "SendUsing" configuration value is invalid.
The configuration between the two servers is quite different. Using the $config reference from above, I executed $config.Fields | Format-List -Property Name,Value on both servers.
Old server (where it works):
Name : http://schemas.microsoft.com/cdo/configuration/languagecode
Value : en-us
Name : http://schemas.microsoft.com/cdo/configuration/postusing
Value : 0
Name : http://schemas.microsoft.com/cdo/configuration/sendusing
Value : 1
Name : http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory
Value : D:\Inetpub\mailroot\Pickup
Name : http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext
Value : True
Name : urn:schemas:calendar:timezoneid
Value : 1
New server:
Name : http://schemas.microsoft.com/cdo/configuration/languagecode
Value : en-gb
Name : http://schemas.microsoft.com/cdo/configuration/postusing
Value : 0
Name : http://schemas.microsoft.com/cdo/configuration/sendusing
Value : 0
Name : http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext
Value : True
Name : urn:schemas:calendar:timezoneid
Value : 0
It seems that all I need to do to make this work is either configure it to by default send mail to localhost, or to drop the mail in the pickup directory. The IIS SMTP server is already configured to look at this directory.
However, I am unable to figure out where these values are set. They must be set in a file or the registry somewhere but even searching through the C drive looking for phrases like "\Pickup" and "usemessageresponsetext" and so on have not revealed anything. If they are somewhere I guess they're in a binary datastore somewhere.
All samples for CDOSYS involve configuring the CDO.Configuration or CDO.Message instance directly but all throughout the code our application loads the configuration from IIS, so somehow this was set at one point by someone.
I missed out on the classic ASP era so I am in very unfamiliar territory. That said, my coworkers who were active classic ASP developers do not know how to configure this, and the original person who set this up has since moved on. It's entirely possible that I'm missing a very simple basic concept here.
I discovered that I was able to use my sample Powershell script when I was logged in as an administrator. Research from that lead me to a post on the IIS forums which has a solution for the issue. Unfortunately it now leads to some dead links which mean it doesn't work. It had enough hints however to put together a solution:
Download and install the IIS Resource Kit Tools.
Execute C:\Program Files (x86)\IIS Resources\Metabase Explorer\MBExplorer.exe as an administrator.
Navigate to /LM/SmtpSvc, right-click on it and select Properties.
Enter the groups you want to give access to. In my case it was both Users and IIS_IUSRS with read access only.
Navigate to /LM/SmtpSvc/1, and set the same permissions on this node also.
Grant read/write access to IIS_IUSRS and Users to c:\inetpub\mailroot
So, the root cause was that the user I was trying to execute this under did not have the correct permissions.
Regrettably I couldn't figure out how to script these steps. The post makes reference to a "metaacl.vbs" script that I couldn't find anywhere; all links that claim to have it are dead. It's also meant to be installed by the IIS Resource Kit tools linked above but I couldn't find it anywhere on my server.
If you could find that somewhere you'd be able to perform the above steps like so:
cscript metaacl.vbs IIS://LOCALHOST/SMTPSVC %computername%\IIS_IUSRS R
cscript metaacl.vbs IIS://LOCALHOST/SMTPSVC/1 %computername%\IIS_IUSRS R
I have an application which has been upgraded from Visual Studio 2010 (running on Windows Server 2003) to Visual Studio 2013 (now running on Windows Server 2008). One aspect of the app allows the user to upload an xlsx sheet to a folder, and a script validates its contents.
I have this method:
Private Function GetValuesFromExcel(ByVal strFileIn As String) As DataSet
Dim ds As DataSet = New DataSet
Dim strConn As String = ""
Try
If strFileIn.ToLower().EndsWith(".xlsx") Then
'This one is good for files that are saved with Excel
strConn = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" + strFileIn + "'; Extended Properties=Excel 12.0 Xml;"
Else
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source='" + strFileIn + "'; Extended Properties=Excel 8.0;"
End If
Dim conn = New OleDb.OleDbConnection(strConn)
conn.Open()
Dim dtExcelTables As DataTable = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
Dim strExcel As String = "select * from [" + dtExcelTables.Rows(0)("TABLE_NAME").ToString() + "]"
Dim myCommand = New OleDb.OleDbDataAdapter(strExcel, strConn)
myCommand.TableMappings.Add("Table", "table1")
'myCommand.Fill(ds, "table1")
myCommand.Fill(ds)
conn.Close()
Catch ex As Exception
DBUtils.WriteToLog("Error", "GetValuesFromExcel", ex.Message, Security.GetCurrentUser())
Throw ex
End Try
Return ds
End Function
On conn.Open(), it throws an error. Specifically, the most excellent error of, "Unspecified Error". Very helpful.
We are using Office 2007, and I have checked to make sure that the 32-bit Access Database Engine redistributable is indeed installed.
What the heck is the problem?
I'll noodle about this a little bit, pretty unlikely you are going to get a "push this button to solve your problem" answer.
The error you are getting is E_FAIL, a generic COM error code. Commonly used by Microsoft software when it does not have a decent guess at the underlying reason for a failure. And guessing at a more specific one is too risky, sending their customers into a rabbit hole. This is a liability of COM in general, it does not directly support exceptions, only error codes. So a major feature that's lost is the stack trace, a cue that can give a lot of information about the specific layer in which the error was detected.
The only real way to deal with them is by a process of elimination. Which is feasible here, the code fails early. The only thing that you can do wrong is supplying the wrong connection string, providing bad data or running the code in the wrong execution context. Ticking off the common mistakes:
Bad connection string syntax. Not your problem.
Invalid path for the file. Not your problem, produces a good message
File is not actually an Excel file. Not your problem, produces a good message
Trying to run this in a 64-bit process. Not your problem, good message.
The not so common mistakes that are not easy to eliminate:
Program runs as a service with an account that has accessibility problems. Eliminate that by testing it with a little console mode app.
The file is an .xlsx file but it is subtly corrupted. Eliminate that by testing with a set of other .xlsx files.
Which does leave the most likely reason:
The OleDb provider is not correctly installed. Classically also the common reason for Microsoft code giving up with a generic error like E_FAIL. Hard to diagnose of course, you might get somewhere by using SysInternals' Process Monitor and comparing a good trace with the bad trace. Good to discover a missing file or registry key. Do keep in mind that installing the 32-bit Access Database Engine redistributable after installing Office is not a good idea, it was meant to be used only on machines that don't have Office available. You'll have to spin the re-install wheel of fortune wheel at least once.
Perhaps the misery is also a good reason to give up on these providers. The EPPlus library is getting pretty good reviews, also scales quite well on a server.
I'm going to second Hans' idea of possibly giving up on these providers and looking into alternatives.
I recently went through a similar issue to that which you are facing. I developed a solution that worked well on my machine, but didn't on others due to them not having the requisite drivers installed.
My situation was a Winforms app that would be installed on clients machines and I would have no control over what external providers (ACE, JET etc) were installed. We also have no idea of what versions of Office they had installed. It was either we provide a convoluted solution that was capable of using whatever driver was installed...or look for alternatives.
We chose the latter, and went with Excel Data Reader. After about 30 mins, the solution now works without relying upon the configuration of the machine it is deployed to.
My code needed to simply read data from an Excel file (generated from an SSRS report) into an in memory DataTable for a bit of data comparison. The method we ended up with shows how simple it was to achieve;
/// <summary>
/// Read data from MS Excel saved as an export from their SSRS reports.
/// This method uses ExcelDataReader <link>https://github.com/ExcelDataReader/ExcelDataReader</link>
/// to avoid dependencies on OleDb Jet or ACE drivers. Given we can't control what is installed on
/// client machines, we can't assume they'll have the correct drivers installed, and therefore we'll
/// make use of ExcelDataReader.
/// </summary>
/// <param name="filename">Filename to the path of the Excel (xls or xlsx) file.</param>
/// <returns>DataTable containing the required data or null if no data is found.</returns>
private DataTable ReadDataFromUsingExcelReader(string filename)
{
DataTable returnval = null;
DataSet result = null;
using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
if (filename.EndsWith("xls", StringComparison.OrdinalIgnoreCase))
{
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream))
{
result = excelReader.AsDataSet();
}
}
else if (filename.EndsWith("xlsx", StringComparison.OrdinalIgnoreCase))
{
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream))
{
result = excelReader.AsDataSet();
}
}
}
returnval = result != null && result.Tables[0] != null ? result.Tables[0].Copy() : null;
return returnval;
}
Okay, so I figured out the issue as it pertains to my situation... I stuck with the ACE.OLEDB drivers, because I knew I could make them work in this scenario. Also, I figured it was something stupid and small. It was.
The xlsx sheet gets written into a folder called 'admin->excel_uploads'. Turns out that I had identity impersonate set to true in my config file. The service account I was running on did not have full read/write privs. That solved why it wasn't working locally, because as soon as I turned off impersonation, it worked great. Then on deploy, I just needed to set up permissions to the service account I was running under.
I wrote vbscript inside my html file for my site and I can't get it to work. I know it only works in internet explorer as thats the common answer I see people write with this issue. I am able to get basic vbscript working, but when trying to use filesystemobjects to open a text file nothing happens. Code being used is below.
<Script type="text/vbscript">
Dim fsobj, objtxt, thearr
Set fsobj = CreateObject("Scripting.FileSystemObject")
Set objtxt = fsobj.OpenTextFile("./subfolder/foo.txt", 1)
thearr = split(objtxt.readline, ",")
document.write(thearr(0) & " and " & thearr(1))
</script>
I get the code to work when saving with asp extension but not when I save as html, is there a way to get it to work with only using the html extension? If not does someone have an explanation as to why scripting filesystemobject without the asp extension doesn't work? I seem to can't search for the answer I'm looking for.
When you were using the FileSystemObject from an ASP page, then you were manipulating the file-system of the server. This is permitted.
However, when you use the code above, you are executing the code on the client. It is not permitted to access the clients file-system from inside Internet Explorer, as it would have serious security implications. The technical term is "sandboxing".
If you need to interact with the file-system on the client machine, you will need to use a technology such as ActiveX.
When you run the script as client script, it would try to access the file from the client computer, not the server. The file isn't there, and even if it was, your script would not be allowed to access it.
You should consider using HTML Applications by renaming your file with a .hta suffix.
An HTA executes without the constraints of the internet browser security model; in fact, it executes as a "fully trusted" application.
HTML files running inside internet browsers are considered as "untrusted" because the code comes from the internet, and is generally considered as "untrusted" as such the browser enforces a tight security model that prevents those HTML pages gaining access to your computer, which is why the FileSystemObject is unable to open the text file. However, as a HTA it is no longer being run by your browser, but via Microsoft's MSHTA application which grants your script full trust.
For more information see HTML Application - Wikipedia.