Using dialog Windows in SQL external procedures - c#

I wrote dll for my SQL database which takes BLOB data from tables and converting it into pdf file. It works good, but i try to add dialog window for choosing pdf saving path and it gives me next message:
System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.
May be someone know what's problem?
dll code where issue is:
public static void Run(SqlInt32 i)
{
FolderBrowserDialog fd = new FolderBrowserDialog();
fd.ShowDialog();
string save_pth = fd.SelectedPath+'\\';
if (gener_pdf(gener_jpg(i, save_pth), save_pth))
{
List<string> to_del = gener_jpg(i, save_pth);
for (int p = 0; p < to_del.Count(); p++) { File.Delete(to_del[p]);}
}
}

The exception message already tells you quite precisely what the problem is:
Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation.
As pointed out in the comments, SQL Server is not a user interactive process; it's a service.
You say that you "need" to do this (presumably, that you need to show the user a dialog box to choose the save path), but quite simply, doing so is wrong on every level. Not least of which being that, as also pointed out in comments, it's extremely unlikely that anyone will be logged in to the machine running the SQL Server process, so there's no one to respond to the dialog prompt.
There are apparently ways to display a dialog box from a non-user-interactive process, but that still assumes that someone is waiting for it to be displayed on (in this case) the database server machine. The odds of this appear to be slim.
Reconsider what you are trying to do, and how. If you absolutely need the user to provide a location and file name on the database server to which to save the generated report, gather that information up front via whatever UI they're working with instead of during the execution of the database code.
More likely you should just put the PDF somewhere (anywhere) with a randomly generated name (which in turn is stored in the database), or even as simply a binary blob in the database, and then offer the user a way to download the PDF thus generated via whatever interface you already have for the user to interact with the data. Doing so will completely circumvent the problem, while maintaining a clear layer separation.

Related

Save user settings for different users in WinForms?

I want to have a save preference option in my WinForms application. The user chooses yes/no and has an option to save preference, upon which the yes/no will be remembered and a form for such a choice will not be popped upon further re running the application.
I read about going to setting and changing but how to do it for different users, since all of them would choose for diff options and I need to maintain that.
Simply using a boolean variable will not help since it will be single user specific. Any suggestions?
(1) At event close main form, you call method/action save result. See How to save data when closing event happen in WinForms?
You can save it to XML file (or text file, SQL lite, SQL Server, etc), popular way is XML file(s).
Read XML file to get saved result before processing business logic in your WinForms application at Load form event or another event type at early stage of application start-up period.
(2) You also save result at previous period in config file https://stackoverflow.com/a/453230/3728901
Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file
So since i didn't want a database , I am creating a file at the client side and saving the preference there.
At run time , I will read from the file and upon that , will decide whether to send form or not .
you can use a Model and store use selected config into it then you should serilaize it and save on database for specific user when reRun the application you can get config and deserialize it to Model and use it

c# runing code without blocking navigation

I'm building an application that generates excel files in asp .net core 2.2.
The excel generation may takes some time depending on the user's needs. (like sometimes, it's up to 20-30s).
My question is : how can I run this generation without blocking user's navigation?
Like, the user could starts the file generation, then continue his navigation on website and come back later to download the generated files. What would be the way to do so?
Run generation in a background task. generate name of the excel file and save the relation either in DB or in tokken (depends on your needs). when the thread will generate excel file update status in db. you can notify user or let user see the info on specific page. there are a lot more ways to do it tho...
Not much a technical, c#-specific question, but more like a UX problem.
You could leave a button the user can click on to request the generation of said files. You run a service that receives such requests, and start processing.
When the service starts the generation, the page simply shows a message saying "Please wait, generating...".
When it finishes, change the page content to a link that allows the user to download it.
In JS you can open a new tab, and you will be processing the excel file in this new tab.
Or, you can create the excel file on the serveur (displaying that its's currently being created), without blocking the navigation, and when your user comes back to the generating page, if a file is found, you can make it downloadable.

Make last change to database when program has crashed/been terminated?

I have an app where user can work on a file downloaded from database. When file is downloaded, in database query is run setting "owner" value in corresponding table row. As a result other users see that file is owned by somebody else and can only read from it, not modify it. After work session user saves file to database and sets "owner" to none allowing other users access file. This works fine till app crashes or there is power shortage or some error in system that terminates app leaving database entries "reserved". In case of crash I can follow this approach :
WPF global exception handler
and try to connect to database to "free" all files reserved by user, but in other cases as my research has shown there is no way how to know that program failure has occured and I should "free" database so other users can access previously reserved files. Is this way how to show other users that something in database is not awailable for editing is in general bad design or there are solutions to this type of a problem?

Add button and custom functionality to adobe reader

I am working on a WPF 4.5 application which needs to interact with PDFs and I am stuck with an issue as described below:
I have template pdfs stored at a specific location. Based on requirement, a copy of the template pdf is created. This pdf has certain fields including text boxes, dropdowns etc. Some of these fields need to be pre-populated like the dropdown values.
Once it is ready, I need to open it, and let the user complete the form. Once completed, the user saves the file and closes it.
Now I need to read the file and send the updated data to the DB. I was able to do all this using iTextSharp by launching the PDF in a separate process and handling the Exited event. Now, the problem I face is this solution does not work if the user uses the SaveAs option to change the name or location of the opened file.
I thought if it would be possible to disable the Save options and add a button on the form clicking which would automatically save the form and close it at the expected location would be a possible solution.
My questions are:
1) Is it possible to find out using the argument of the Exited event handler to find out the saved file name and location? As soon as the user saves the file with a different name, the title of the reader gets updated with the current file name. So I am assuming that the current process is using the latest file.
2) Is it possible to disable the SaveAs and Save file options and close the file on click of a button in the form, using Adobe SDK (JavaScript or plugin or API)?
3) If I use the Adobe SDK, do all the systems on which the application would be installed need to have a licensed version of the Adobe Acrobat?
If the above options are not possible then we would have to settle with dynamic forms. We wanted to experiment with PDF since it is easy to create, and supports image annotations, for which we might need to develop a separate solution, if the above options are not feasible.
I know this is not a very specific programming question, but I need help in order to be able to figure out which path I can go on to be able to achieve the goal.
Please mark duplicate with the link to the other SO question if it a duplicate since I have not been able to figure out one.
Would appreciate answers, links to other posts on SO that are specific to the questions asked.
Please avoid opinion based answers.
Any help would be appreciated.
Any constructive criticism is also welcome.
There is a heavy-handed way to prevent an Acrobat user from Saving a file. In Acrobat, create a Javascript that executes when "Document Will Save." A script like this causes the application to hang rather than Save the file:
var key = "" + this.getField("Password").value;
if (key != "QWERTY") {
app.alert ("No changes to this PDF are allowed,
so you may not Save it.
You will now have to Force Quit or End Task.");
while (true) {};
}
I am not proud of this, but it does the job. You might want to erase the password field before saving.

Replace save file dialog opened by any program by a customized save file dialog

I am working on a Version Control/File Sync System for Windows. It would be great to have a checkbox at the bottom of the classical save file dialog with the option to check/uncheck for my file versioning.
Is it possible to listen for opened save file dialogs by any program (word etc.) and replace/override that dialog with a customized one (with an additional checkbox)?
If the checkbox is checked, another window should pop-up where the user could enter some additional metadata. After that the data is stored in a local database.
I already worked with the approach by dmihailescu (link provided) but it's very complex and I do not know how to modify that example to listen for opened save file dialogs by other programs.
http://www.codeproject.com/Articles/19566/Extend-OpenFileDialog-and-SaveFileDialog-the-easy?msg=4779306#xx4779306xx
Another approach is to use the FileSystemWatcher but that's very expensive to watch the whole system and it's not very comfortable because the user has to be asked for any created file if he/she wants to version control it.
I hope someone could help me to solve that problem or has some additional tips / approaches.
Thank you.
Edit: Use-case
A user has to write a documentation and creates a new word-doc. When he/she clicks the Save as menu entry of word, my customized save file dialog should pop-up with a checkbox at the bottom, if this file should be versioned or not. If the checkbox is "active" a new window should appear where the user could enter additional metadata. After that the data should be stored in local database.
In my case, only the metadata (like the path etc.) should be stored in the database. Let's suppose a user stores the same file in two different directotries (one file is "older" and one file is the current one). If the user opens an older version of this file, my system should recognize that a "newer" one is already stored in another place and synchronize those files.
That should just be a very easy example.
You have two pieces of functionality: save and version-control. Both of the tasks are actually rather complicated. Therefore you shouldn't mix them. You better off using standard Windows API to save file and do not change that. Think about how you'd support several different Windows releases and how painful that would be.
I assume you have your own UI, and do not integrate with, say, Windows Explorer (like Tortoise Svn or Dropbox). In this case you can do version-control magic first and then just save the end file using standard API.
If you do integrate with Windows Explorer, I suggest you to have a look at Tortoise svn source code.

Categories