Using WinAPIServer and SysExcelApplication class in batch job - batch-file

I created a batch job that creates an Excel file populated with query, the problem is the following:
I used WinAPI and SysExcelApplication classes in my code. After debugging, I saw that these classes causes problems when launched with batch job. I used winAPIServer and managed permissions with fileIOPermission class and my problem remains.
When launched without batch job my code works perfectly, no errors.
Does anyone has ideas to solve my problem?
here's the error message:
The session server-side substitution (RunAs) attempted to invoke a method that is not available for client-side processing only.

RE the WinAPI side of things, there is a WinAPIServer class that does the same thing as WinAPI. There's an example of the code I use:
if (xGlobal::clientKind() == ClientType::Client)
{
winapi::copyfile(File, strReplace(File,SourceFolder, FailureFolder));
winapi::deletefile(File);
}
else
{
winapiServer::copyfile(File, strReplace(File,SourceFolder, FailureFolder));
winapiServer::deletefile(File);
}

You can't use SysExcelApplication from a batch job that executes on the server because Excel is a client application that needs to get access to client UI and this is not compatible with impersonated service execution.
I know that this is not as logic as it should be, but I got this answer from the Microsoft Engeenering Team, some months ago when I faced this problem on a client.
Posible solutions are don't use Excel at all if you can avoid it by using CSV files or something like that; Or make those batches run on the client layer, wich forces you to always have a client open running batches on a client session (and consuming a client license)

In Dynamics AX, you can create an xml file. Then create and call a PowerShell script to convert the xml file to an excel file. And this can all be done inside a AX Batch Job.

Related

Automate the execution of a C# code that uses Entity Framework to treat data?

I have code that uses Entity Framework to treat data (retrieves data from multiple tables then performs operations on it before saving in a SQL database). The code was supposed to run when a button is clicked in an MVC web application that I created. But now the client wants the data treatment to run automatically every day at a set time (like an SSIS package). How do I go about this?
But now the client wants the data treatment to run automatically every day at a set time (like an SSIS package). How do I go about this?
In addition to adding a job scheduler to your MVC application as #Pac0 suggests, here are a couple of other options:
Leave the code in the MVC project and create an API endpoint that you can invoke on some sort of schedule. Give the client a PowerShell script that calls the API and let them take it from there.
Or
Refactor the code into a .DLL or copy/paste it into a console application that can be run on a schedule using the Windows Scheduler, SQL Agent or some other external scheduler.
You could use some tool/lib that does this for you. I could recommend Hangfire, it works fine (there are some others, I have not tried them).
The example on their homepage is pretty explicit :
RecurringJob.AddOrUpdate(
() => Console.WriteLine("Recurring!"),
Cron.Daily);
The above code needs to be executed once when your application has started up, and you're good to go. Just replace the lambda by a call to your method.
Adapt the time parameter on what you wish, or even better: make it configurable, because we know customers like to change their mind.
Hangfire needs to create its own database, usually it will stay pretty small for this kind of things. You can also monitor if the jobs ran well or not, and check no the hangfire server some useful stats.

How to store the result of an SQL query to an XML file in a specific folder without using cmdshel

I have an SQL Server query and I am using FOR XML PATH to generate the result as XML. I am trying to save the file result.xml to a particular folder of my computer but I do not want to use the "save as" link of SQL Server to do it, because I need to automate my process.
Unfortunately, I cannot use xp_cmdshell solution provided here because I do not have the permissions to do it. In fact I get an error
The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'
each time I try to execute it.
May anyone help me with that? It would be highly appreciated!
Good day,
like always there are lot of solutions which depend on your knowledge and resources. I will try too give you some ideas here and probably others will be able to add more
Using SQLCLR you can simply create a file and save it (this will require using PERMISSION_SETUNSAFE)
Using Python (basically same as SQLCLR we can do everything with Python including external tasks).
You mentioned that you do not want to use xp_cmdshell at first but after the short discussion I understand that you simply do not succeed to use it, but this is your preferred option. Check this thread on the same topic. You should find the solution there on how to configure the permissions.
Using sp_send_dbmail you can send the result of the query to email. Not like other options this is usually open in most servers. The idea is to send simple email, and using Google Apps you can read the content of the email and create file. You can use for example the methods: GmailApp.getInboxThreads, getMessages(), getRawContent()... and in order to write the file in your Google drive you can use DriveApp.createFile
Using SSIS
Following your advice I took the time to learn how to use C# in order to solve my problem and now it works perfectly! I created a short script that executes my sql query using for xml path and then managed to save the resulting XML file in a specific repertory. Thank you again for the support. So my process is now fully automated. Always nice to learn more!

Execute SQLCMD from Asp.net through Angularjs

I can't seem to find anything related to this problem. So I have a web-app I'm building using AngularJS and the others (html,etc) for UI, which connects with an Entity Framework in Asp.net (Either API or MVC, I'm not sure) for rest calls. That then connects to a sql database for model retrieval.
I have a SQLCMD which executes a stored procedure and creates a new time-stamped file of records from the database. The idea is that users will be able to click a button in the interface and a file will be generated without anyone ever having to touch sqlserver that they cna then put into excel. This has lead me on a search of topics like "WebMethods to call sqlcmd", "Calling .net webmethods with Angularjs", and "executing stored procedures with ASP.net", but nothing seems to be similar to what I'm asking (which leads me to believe maybe I don't have the best idea and it can be done better).
Any ideas? Just some pointers on where I should start or how I can tackle the problem would be greatly appreciated. I don't even have to return anything, it just needs to execute so this file can be created.
Your problem has nothing to do with AngularJS.
AngularJS is just some client side code that will eventually call MVC or WebApi code (as you state).
Your problem is .. having server side dotnet code call an external .exe.
http://dotnetslackers.com/community/blogs/haissam/archive/2007/02/02/Run-Executable-file-in-ASP.NET.aspx
// Create An instance of the Process class responsible for starting the newly process.
System.Diagnostics.Process process1 = new System.Diagnostics.Process();
// Set the directory where the file resides
process1.StartInfo.WorkingDirectory = Request.MapPath("~/");
// Set the filename name of the file you want to open
process1.StartInfo.FileName = Request.MapPath("WindowsMediaPlayer.exe");
// Start the process
process1.Start();
You just need to get familiar with System.Diagnostics.Process.
One big gotcha will be permissions (that is running the IIS) being able to run sqlcmd.exe.
I ended up doing a completely different idea and exported directly from Angular, Export to xls using angularjs, and did'nt worry about .NET or SQL for it.
This was way simpler and is better for me since the user can actually select what they want to export rather than just a total database dump.

Intellij Idea: Editing Groovy code stored in database

I have business logic coded in Groovy and stored in a database table. I would love to edit this code inside Intellij IDEA with all the code completion possibilities etc. provided by this great IDE.
I could copy the script from the database table into a temporary file; edit it and store it back into the database. I could also write a plugin. But is there maybe already a way to do this with IDEA?
As I know, you can create "External tool", calling a simple import/export script, that will allow you to automate some tasks, you'd like.
Writing plugin isn't very simple task, and is an overhead as I think.
Also, you can use some wrapper inside your application, to work with debug configuration, when buisness logic scripts are loaded directly from files. It will also allow you to autoreload them, using groovy integration features. GroovyScriptEngine

MFC application: Embedded batabse on windows mobile 6 SDK return with an error while writing to DB

I am implementing a database on wince platform in EDB. I have created and successfully tested all database operations in MFC simple dummy database application.
But when I have integrated database API into my project it create problem.
Scenario:
I am able to create database using CeMountDBVol(...) API with EDB flag on.
A table is created into the mounted volume (volume is a database in EDB world) by CeCreateDatabaseWithProps(...) API.
API CeOpenDatabaseInSession(...) opens the database successfully.
I need to call open database call two times from different functions. 1st time after creation of database and 2nd time before writing to database.
Now when I am call API CeWriteRecordProps(...) to write record to database it return with any error code 32 which means "The process cannot access the file because it is being used by another process.".
Here I am not getting which process it is trying to access. Your help will be appreciated.
This is my first questing, please forgive me if question forming is wrong.
Sorted out the problem :)
It was failing because of twice the calls for open database. EDB does not give close database call. My code is trying to open the table(EDB calls it as database) which is already opened.
I removed the 2nd open database call and it returns success.
Thank you.

Resources