How can I open an Office Document from sql server via my C# windows app and automatically save back to database when editing is done? - sql-server

Our application is written in C# using .net 2.0. The application tracks our business process and users can attach office documents for reference as attachments. They frequently edit those documents. Currently, they have to save the file to their hard drive, edit and save the file, then re-attach to our application to save into database (SQL 2005).
Our users would like to be able to edit the document and save the changes without needing to detatch, edit, and re-attach.
We can programmatically launch the office (word, excel or powerpoint) document, but how can we tell when the document has closed and re-attach the updated version to the database automatically?
Thanks for any help.
Joe

You may have a designated directory (e.g. Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) where you keep the files currently edited and put a FileSystemWatcher to watch whether the file changes.
The Diagnostics.Process class also has an "Exited" event that will notify you when the process, well, exited.

Look into SmartDocument technology at MSDN. Of the three productivity apps you mention (Word, Excel, Powerpoint) the first two for sure, and possibly Powerpoint, can have the right side panel -- where you usually see styles, navigation, or tasks -- programmed through VS using SmartDocument and Tools for Office plugins.
So, you can program the panel such that the user, working in Office or Excel (and possibly PP -- haven't looked into that) can select the document to be edited from your application, do the edits, and save/attach the document, all from the Word interface. The programming behind the right side panel will automagically take care of detaching, and reattaching the document, and can also save the document to SQLServer, if you like.
Hope this helps.

If you are launching the file by using Process.Start method and passing file path as a parameter, you can use the WaitForExit() method to be notified when the user has closed the file.

Related

Dealing with server stranded file uploads

I have an Angular SPA app running on Azure and I'd like to implement a rich text editor similar to Medium.com. I'll be using some existing editor for this, but I have a problem with image files.
The problem
I would like my editor to have the ability to also add images inside content. The problem I'm having is when should I be uploading images to the server?
Possible solution 1: Immediate upload after they're selected
The good
saving content is quicker because all images are likely already uploaded
files get displayed right after they're uploaded from the server URL
The bad
files may have to be deleted on the server if users selects to cancel editing
files may get stranded on the server if user simply closes their browser window
Possible solution 2: Upload after save
The good
files get displayed immediately using FileAPI capabilities
no stranded server side files if editing is discarded in whatever way
The bad
saving of content may take longer as all images need to be uploaded at the moment of saving content
additional client-side to display images from local files
Question
I would like to implement Solution 1 because it provides more transparent user interface process and reacts quicker to edit saves => better UX. But how should I be managing stranded files? I could use a worker process that would delete stranded files from time to time, but I wonder whether that's the best approach for this scenario.
What and how would you suggest I implement this?
This is highly subjective (opinion based), but I will give it a shot.
You are actually having bigger problem than you think. In your abstracted approaches, you only describe a situation when user started something as new. Whereas I see much harder to solve issues if user is editing existing item. What will happen if he/she deletes images, adds new images and at the end hits CANCEL. And also, if Internet connection drops while creating / editing?
I would also go for Solution one. And, of course minimize the "bad" things, as they aren't really that much or hard to handle. Here is how I would solve all the "bad"s in Approach 1:
All my articles (or whatever user is editing with editor) will have a boolean flag "IsDraft" or something like this. Then all my business logic for front end will only look for items where IsDraft == False.
Whenever a user starts a new article (the easiest to solve problem) I immediately create new item in my DB with IsDraft=True
Have a link table to keep link between ID of item being created and Image Files being used (blobs). The point here is, that, if you do not keep links between used and unused blobs, you will have a lot headaches deciding which blob to delete and which one to leave on the storage.
Have a worker process (either as worker process in Web Role if I use Cloud Services, or as a Web Job (+ nice and short explanation here) is I use Web Sites) that checks for articles that are Draft and older than XXX days. If found - delete files + article itself.
Handling Editing of existing item is more challenging - for this, I might take the approach of:
Create a new copy of the entire article when user hits Edit and mark it as draft
If user hits save - switch the content of the new article (new version) with the existing one, leaving the new article marked as IsDraft - the worker process will clean it up.
If user doesn't hit save for some reason (hit cancel, or internet drops, or computer restarts, or browser crashes, or or or ..) - the new article will be cleaned later by the worker process
And if you want to go deeper and crazier, you can have a section in your admin panel where you show the Drafts to your users, so they can either continue work, or leave it to be auto cleaned.

save an Access database with restricted permissions for users

I have a question about a feature and I don't know if it's applied in Microsoft Access or not. After I finish my database tables, forms and reports, I want the user just to open forms and these forms will do most the tasks which are adding, deleting or modifying the records. I don't want the end user to see the other object such as tables, or to view or change the layout of the forms.
Is there any way to save the database just as exe file or limiting the permissions of the end users?
Since no version is supplied, I'll give you what I know about MS Access 2007.
Take a quick look at this page
What you need is to convert your accdb file to accde. This will hide the navigation pane and forbid any action from being taken on your forms.
An .accde file is a "locked-down" version of the original .accdb file.
If the .accdb file contains any Visual Basic for Applications (VBA)
code, only the compiled code is included in the .accde file. As a
result, the VBA code cannot be viewed or modified by the user. Also,
users working with .accde files cannot make design changes to forms or
reports.
The same was also true for earlier versions, i.e. mdb to mde for Access 2003. I am sure that there is something for newer versions of MS Access as well.
Hope I helped.

Creating a custom column: "Append-Only" File Upload

I'm trying to make a custom column (for a custom list), where the users can upload files without overwriting the previous - this way they can keep past versions of the files and upload newer ones and the new ones append. There already exist "append only" comment columns and file upload columns that I can see.
I'm working with Sharepoint designer 2007 (2010 doesn't work with the site), and I'm referencing this code I found online somewhere (http://pastebin.com/raw.php?i=0qN89meu), trying to research the Sharepoint documentation on MSDN. I can open the site in designer, but don't know where to go from there (it's already running on a web server, not opening it locally).
I'm just not clear on how to start, I thought there'd be a simple "right+click -> new column" feature but I can't find it. If someone could point me in the right direction to where I could start creating columns on the site, that would be great. Thanks!
An untested idea :
Create a document library with a lookup column to the custom list.
Create an event receiver (ItemAdded and ItemUpdated) than will take the attached files and move them to the other list (with the correct lookup value). --> Code with Visual Studio
Grant to this document library only read permissions.
Adapt the view to display the related documents in the dispform of the custom list.
Advantages:
this seems to answer to your need
you gain all the usability of a document library (nothing prevent you to grant edit rights to other users, force check out, etc.)
Disadvantages:
you have to play with lookup. Can be tricky sometimes, if you play with features
you split one business entity to two entities. You will have to deal with cascading delete (if you need it).

Using Excel with Silverlight app not writing new columns

I have a project as follows:
User uploads Excel file to server, server will return back with 2 new columns. User wants us to check prices being charged and we have file that holds average standard pricing.
In the desktop application just done, I use Microsoft.Office.Interop.Excel
for manipulating the Excel file.
But this is not available in Silverlight. Reading is not the issue.
The issue is adding 2 new columns. Program reads excel file using oledb, and oledb is very light and is available in web.
But for creating 2 new columns, I use Microsoft.Office.Interop.Excel that Microsoft provides.
This is not available in web.
I will be need to check how can we do this.
One possibility is to have the program on the server, waiting for a file, process the file, and email back to the user.
I just want to see if there is another way. I don't like this approach it doesn't seem best.
You have a few options for doing this with Silverlight. First, you can use the Excel XML format for the files which means adding a column is just an XML exercise. Second, if that doesn't work, you can upload the file to the server and run the same code you have in your desktop app to update the file. Once it is updated you can prompt the user to save the file back to their hard drive.
If you go the Excel XML route then you would need to create a web service to get the price data from your database out to the Silverlight on the client. Oledb won't work since you don't want to expose your database via oledb on the Internet.

SQLite vs.SQLCE Deployment

I am in the process of writing an offline-capable smartclient that will have syncing capability back to the main backend when a connection can be made. As a side note, I considered the Microsoft Sync Framework but since I'm really only going one-way I didn't feel it would buy me enough to justify it.
The question I have is related to SQLite vs. SQLCE and ClickOnce deployments. I've dealt with SQLite before (impressive little tool) and I've dealt with ClickOnce, but never together. If I setup an installer for my app via ClickOnce, how do I ensure during upgrades the local database doesn't get wiped out? Is it possible to upgrade the database (table structure, etc. if necessary) as part of the installer? Or is it better to use SQLCE for something like this? I definitely don't want to go the route of installing SQL Express or anything as the overhead would be far too high for what I am doing.
I can't speak about SQLLite, having never deployed it, but I do have some info about SQLCE.
First, you don't have to deploy it as a prerequisite. You can just include the dll's in your project. You can check this article which explains how. This gives you finite control over what version is being used, and you don't have to deal with installing it per se.
Second, I don't recommend that you deploy the database as a data file and let ClickOnce manage it. When you change that file, ClickOnce will publish it again and put it in the data directory. Then it will take the previous one and put it in the \pre subfolder, and if you have no code to handle that, your user will lose his data. So if you open the database file to look at the table structure, you might be unpleasantly surprised to get a phone call from your user about the data being gone.
If you need to retain the data between updates, I recommend you move the database to the [LocalApplicationData] folder the first time the application runs, and reference it there. Then if you need to do any updates to the structure, you can do them programmatically and control when they happen. This article explains how to do this and why.
The other advantage to putting the data in LocalApplicationData is that if the user has a problem and has to uninstall and reinstall the application, his data is retained.
Regardless of the embedded database you choose your database file (.sqlite or .sdf) will be a part of your project so you will be able to use "Build Action" and "Copy to Output Directory" properties of that file to control what happens with the file during the install/update.
If you choose "Do not copy" it will not copy the database file and if you choose "Copy if newer" it will only copy if you have a new version of your database file.
You will need to experiment a little but by using these two properties you can have full control of how and when your database file is deployed/updated...

Resources