How do I open a file with my application? - c#-4.0

Ok, you know how in programs like Microsoft Excel, or Adobe Acrobat Reader you can click on a file in explorer and it will open with the associated program. That's what I want my application to do. Now, I know how to set up the file associations in Windows so that it knows the default program for each extension. My question is how do I get my application to open the file when I double click the file.
I've searched the web using google, I've searched the msdn site, and I've searched several forums including this one but I haven't found anything that explains how to accomplish this. I'm guessing it has something to do with the parameters of the main method but that's just a guess.
If someone can point me in the right direction I can take it from there. Thanks in advance for your help.
Shane

Setting up the associations in windows will send the filename to your application on the command line.
You need to read the event args in your applications main function in order to read the file path and be able to open it in your application.
See this and this to see how to access the command line arguments in your main method.
static void Main(string[] args)
{
System.Console.WriteLine("Number of command line parameters = {0}", args.Length);
foreach (string s in args)
{
System.Console.WriteLine(s);
}
}

When you open the file, with associations set as you described, your application will be started with the first argument containing the filepath to your file.
You can try this out in a simple way by printing out the args from your main method, after you open your application by clicking on the associated file. The 0th element should be the path to your file.
Now, if you successfully reached this point, the all you need to do now is read the contents of the given file. I'm sure you'll find more than plenty of resources here on how to do that.

I guess this is what you are looking for:
FileInfo fi = new FileInfo(sfd.FileName); //the file you clicked or saved just point
//to the right file location to determine
//full filename with location info
// opening file
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #fi.FullName;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();

You will need to create registry-keys for your file-extension. This page describes well, which keys you'll need to set (see «3. How do I create file associations?»).

Related

AddApacheModRewrite method suggesting that file doesn't exist (when it does)

Just trying to put an ApacheModRewrite call in my .NET Core 3.1 web application, and no matter what I do, it keeps telling me that the file does not exist. I've verified that the file exists at that location, I've tried creating a custom PhysicalFileProvider, and I've tried to set the file as Content/Copy Always, but no matter what I do, I cannot get past this code:
var options = new RewriteOptions()
.AddApacheModRewrite(env.ContentRootFileProvider, env.ContentRootPath + ".htaccess");
And the error:
System.IO.FileNotFoundException: 'The file F:\Source\MyWebsite\htaccess.txt does not exist.'
Where env.ContentRootFileProvider resolves to path: "F:\Source\MyWebsite" and again I have confirmed that the .htaccess file does, indeed, exist. I've also tried a variety of different ways to access the file path in the AddApacheModRewrite, but I'm really scratching my head on this one.
What am I doing wrong?
Figured it out. I had to use a streamreader, read the file, and then was able to apply it:
using (StreamReader apacheModRewriteStreamReader
File.OpenText(env.ContentRootPath + "\\.htaccess"))
{
var options = new RewriteOptions()
.AddApacheModRewrite(apacheModRewriteStreamReader);
app.UseRewriter(options);
}

setCacheDuration on Wicket DownloadLink

I am currently using a downloadLink in Wicket to allow a user to download a created excel file, and then to be deleted afterwards. When this is done over SSL IE gives me an error:
"Unable to download.
Internet Explorer was unable to open this site. The requested site is either unavailable or cannot be found. Please try again later. "
here:
http://support.microsoft.com/kb/323308
after doing some reading from the above microsoft support link, it seems it is because
because it's over SSL, and I have
response.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store");
I set my downloadLink like so:
private void setupDownloadLink()
{
IModel excelFileModel = new AbstractReadOnlyModel()
{
public Object getObject()
{
return excelCreator();
}
};
auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);
auditDownloadlink.setOutputMarkupPlaceholderTag(true);
auditDownloadlink.setDeleteAfterDownload(true);
auditDownloadlink.setCacheDuration(Duration.NONE);
auditDownloadlink.setVisible(false);
findUserForm.add(auditDownloadlink);
}
However, it seems to work if I do: auditDownloadlink.setCacheDuration(Duration.Minute);
I guess I am confused on what is happening with this. Does the setCacheDuration mean how long after the file is created, it will be available for before it is deleted? Or does this mean how long in total the file will be available for from the start of declaring it?
inside the excelCreator() method I call File excelfile = new File("Access.xls"); and then go ahead and process all of the excel work and create the spreadsheet, then at the end of the method I call:
FileOutputStream output = new FileOutputStream(excelfile);
workbook.write(output);
output.close();
Will the duration time I set start from the moment I call File excelfile = new File("ssaUserIDAccess.xls")?
What is the best duration and setup I should use for this scenario? Because the files can get quit huge, and can take some time to create if it is big enough.
Thanks!
I do not remember the reason, but we had the same problem on SSL/IE and we just set the cache duration to 1 second that is enough. Just it cannot be NONE. Another solution we've never found.
auditDownloadlink.setCacheDuration(Duration.ONE_SECOND)

Open web page in After Effects with ExtendScript

This may be a simple one but I can't figure it out. How can I open a web page in the main browser from extendscript as I would do with window.open() in Javascript?
I am targeting After Effects and would like it to work on both OS X and Windows.
In After Effects you can simply do it using the system object, as Dirk mentioned. However you need several things for that:
checking that the script can access the network:
if (app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY") != 1)
{
alert("Please tick the \"Allow Scripts to Write Files and Access Network\" checkbox if Preferences > General");
// Then open Preferences > General to let people tick the checkbox
app.executeCommand(2359);
// Here you should check again if they ticked it, and choose to continue or stop ...
}
checking of the OS:
var os = system.osName;
if (!os.length)
{
// I never remember which one is available, but I think $.os always is, you'll have to check
os = $.os;
}
app_os = ( os.indexOf("Win") != -1 ) ? "Win" : "Mac"
os-dependent system calls:
var url = "http://aescripts.com";
if ( app_os == "Win" )
{
system.callSystem("explorer " + url);
}
else
{
system.callSystem("open " + url);
}
Provided you have access to CSInterface.js:
cep.util.openURLInDefaultBrowser("http://www.google.com")
One application independent way is to write an operating system's representation of the URL into a file, then execute() the file.
On the Mac that would be a .webloc file. The underlying format is "plist binary", if you prefer to generate xml, create a sample webloc by drag&drop from the browser address and convert it:
plutil -convert xml1 ~/Desktop/sample.webloc
To invoke that webloc, run the ExtendScript
File("~/Desktop/sample.webloc").execute()
You can do anything on your local computer - commandline and anything else in a VBS file, and you can launch a vbs file from javascript like this:
function RunScriptVBS(whatscriptname){
app.doScript(File(whatscriptname), ScriptLanguage.VISUAL_BASIC);
}
Here is your vbs script:
Dim objShell
Set objShell = CreateObject("WScript.shell")
objShell.Run ("http://www.somewhere.com")
set objShell = nothing
The scope of the question apparently has been refined to After Effects (AE), so I add another answer specific to that application.
On my Machine AE CS6 does not produce an object model file for display by the ExtendScript Toolkit. Please retry it yourself, the object model viewer is in the help menu of ESTK.
Anyway, the ESTK data browser does works. If you target AE, you'll see a couple of objects and classes. Eventually check some more menu items in the databrowser panel flyout menu. I had a deeper look at the app object itself (no openUrl() there) and also found a "system" object. Expand that and you see several interesting methods.
The following script opens a URL on the Mac. I have not tried Windows, maybe it is even the same.
system.callSystem("open http://www.google.com")
As this is the first time I launched AfterEffects, I might have missed better ways.

Add a footer to an existing OpenXML spreadsheet

EDIT: There's a further detail I left out with my original post. The program is using a template stream rather than a concrete template for the ".Open" command. The template stream gets initialized with this code block:
public void Initialize(Stream templateStream)
{
spreadsheet = SpreadsheetDocument.Open(templateStream, true);
}
I'm still researching this, but does anyone know the implications of using a stream for the HeaderFooter object in OpenXML?
I'm new to OpenXML and still in the process of reading and learning what I can of this massive SDK. I've inherited a C# MVC.NET program that uses OpenXML to display information on an Excel spreadsheet and all of that is working, but I now need to add a footer to the same spreadsheet and I'm hitting some brick walls in my OpenXML knowledge.
I put the footer information I wanted into the spreadsheet, opened it up with the Open XML SDK Productivity Tool and found this code under <.x:oddFooter(OddFooter):
// Creates an OddFooter instance and adds its children.
public OddFooter GenerateOddFooter()
{
OddFooter oddFooter1 = new OddFooter();
oddFooter1.Text = "&L&\"Times New Roman,Regular\"Page &P of &N&C&\"Times New Roman,Regular\"Generated On: <Date/Time> Central&R&\"Times New Roman,Regular\"Report";
return oddFooter1;
}
And this code one level up under <>x:headerFooter(OddFooter):
// Creates an HeaderFooter instance and adds its children.
public HeaderFooter GenerateHeaderFooter()
{
HeaderFooter headerFooter1 = new HeaderFooter();
OddFooter oddFooter1 = new OddFooter();
oddFooter1.Text = "&L&\"Times New Roman,Regular\"Page &P of &N&C&\"Times New Roman,Regular\"Generated On: <Date/Time> Central&R&\"Times New Roman,Regular\"Report";
headerFooter1.Append(oddFooter1);
return headerFooter1;
}
Now I of course need to append the footer info somewhere, and this is where I'm stuck. In <>x:worksheet(Worksheet) I see this line of code:
worksheet1.Append(headerFooter1);
This looked easy enough, but when I looked back at the application code I found no worksheet object to append to. I thought I was close with the following line of code:
spreadsheet.WorkbookPart.Workbook.Append(headerFooter1);
but this yielded nothing. In the application I see a SpreadsheetDocument object and references to OpenXMLParts... do I need to get a spreadsheet part to append to? Or do I need to take a different approach with a Spreadsheet versus a worksheet object? Do I need to materialize the current worksheet and then append?
I have a feeling this has an easy solution, but as I said I'm still learning the SDK.
Thank you!
For those who don't know about the productivity tool, it is included with the SDK and can be downloaded from https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5124
On my 64 bit machine, the install path to the tool was:
"C:\Program Files (x86)\Open XML SDK\V2.0\tool\OpenXmlSdkTool.exe"
You should be able to manually add a footer to a spreadsheet, and open it up with the tool and see the exact C# required to create the entire spreadsheet, including the footer. You can then remove the parts of the code that are unnecessary, like some of the styles that are automatically added.

UnauthorizedAccessException while scanning directory 'User\Documents\My Music'

Question: Why do I get this error while scanning a users 'My Documents' folder, but not when I scan the 'My Music/My Pictures/My Videos' directory?
Secondary, less important question: Is there a way to avoid this without having to specifically filter these folders out, or using a try/catch block?
I prefer answers that teach me how to fish, instead of just giving me fish. Just at this point I am not sure where I need to look to specifically answer this question. I've read through documents about elevating permissions and iterating through the file system, and spent a good week looking for why I can set DirectoryInfo on 'User\My Music' but not 'User\Documents\My Music'(link) and just would enjoy a little boost in a different direction in regards to learning more.
I catch the initial 'UnauthorizedAccessException' that is thrown initially when attempting Directory.GetFiles('path', "*", SearchOption.AllDirectories) where path is the users 'My Documents'. To handle the exception I know that I need to walk the directory manually. Which works, returning the files from the sub-directories.
The code for the initial GetFiles function:
public static string[] GetFiles(string path)
{
string[] files;
try
{
files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
}
catch(UnauthorizedAccessException ex)
{ files = WalkDirectory(path); }
return files;
}
public static string[] WalkDirectory(string path)
{
List<string> files = new List<string>();
DirectoryInfo dir = new DirectoryInfo(path);
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
try
{
files.AddRange(WalkDirectory(subDir.FullName));
}
catch(UnauthorizedAccessException ex)
{
// complete fail to walk directory listed
throw ex;
}
}
foreach (FileInfo file in dir.GetFiles())
{
files.Add(file.FullName);
}
}
This works out perfectly, until the code attempts to walk the hidden folders: My Music, My Pictures, or My Videos. No matter how I try and re-code to walk the hidden files, I keep receiving the UnauthorizedAccessException.
I understand completely that I am going to code around this. Mainly what I am curious to know, is why is the exception happening under a users folder?
An asssumption I am making is that the folder is a symlink to another directory, because I can make the path ?:\users directory\user\My (Music, Pictures, or Videos) and the code walks those directories then without any issues. This only happens when trying to scan the directory files after setting them from within the users My Documents.
OS: Windows 7
User Privliages: Administrator
Application Elevated to run as administrator
I was speaking about this with a friend, who is not technical, but knows enough tech to hold a conversation and he helped me narrow this question down further. This is actually a duplicate question and was answered at Check if a file is real or a symbolic link.
The folder is a symbolic link that was placed there for backwards compatibility purposes according to this article on TechRepublic: Answers to some common questions about symbolic links under the section Windows Vista and Windows 7 have built-in symbolic links paragraph 2.
In order to specifically avoid attempting to scan this directory without a Try/Catch block on an UnauthorizedAccessException the folder attributes need to be checked to determine if the folder or file in question is a symbolic link. Which again was answered in the above listed stackoverflow question.

Resources