TFS Build CopyDirectory error not stopping build - c#

I have a CopyDirectory step in my build template, and I was assuming that if it finds a directory that does not exist, it would throw errors. However, it is only throwing a warning, and the build itself is marked successful.
I've tried to wrap it around a try/catch block, and manually did a 'throw' exception step, but still didn't work. I tried to set the buildStatus to failed, but that didn't work either. Any another way I can achieve this? I don't want the build to be successful if any of the copy directory fails.
EDIT:
Here is the snippet where the copy directory is. I'm looping over a list of servers and copying a bunch of directories.
<ForEach x:TypeArguments="x:String" sap2010:WorkflowViewState.IdRef="ForEach`1_4" Values="[SCCDServers]">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="server" />
</ActivityAction.Argument>
<Sequence sap2010:WorkflowViewState.IdRef="Sequence_37">
<mtbwa:CopyDirectory Destination="[server]" DisplayName="Copy Code Files" sap2010:WorkflowViewState.IdRef="CopyDirectory_14" Source="[BuildDetail.DropLocation & "\_PublishedWebsites\" & SCWebOutputFolder]" />
<mtbwa:WriteBuildMessage sap2010:WorkflowViewState.IdRef="WriteBuildMessage_16" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="["Code Files copied to " & server]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
<mtbwa:CopyDirectory Destination="[server]" DisplayName="Copy Config Files" sap2010:WorkflowViewState.IdRef="CopyDirectory_15" Source="[BuildDetail.DropLocation & "\_PublishedWebsites\" & SCConfigSourceFolder & "\" & SCCDServerRole]" />
<mtbwa:WriteBuildMessage sap2010:WorkflowViewState.IdRef="WriteBuildMessage_17" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="["Config Files copied to " & server & Environment.NewLine & "Copied from: " & BuildDetail.DropLocation & "\_PublishedWebsites\" & SCConfigSourceFolder & "\" & SCCDServerRole]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
<mtbwa:CopyDirectory Destination="[server]" DisplayName="Copy Sitecore Files" sap2010:WorkflowViewState.IdRef="CopyDirectory_16" Source="[BuildDetail.DropLocation & "\_PublishedWebsites\" & SCSitecoreFilesSourceFolder]" />
<mtbwa:WriteBuildMessage sap2010:WorkflowViewState.IdRef="WriteBuildMessage_18" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="["Sitecore Files copied to " & server & Environment.NewLine & "Copied from: " & BuildDetail.DropLocation & "\_PublishedWebsites\" & SCSitecoreFilesSourceFolder]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
</Sequence>
</ActivityAction>
</ForEach>

CopyDirectory indeed has a bug that only issues a warning when the source directory doesn't exist. It also has problems with long paths (>248 chars).
Possible workarounds:
Use InvokeCommand, running Robocopy.exe (better than xcopy) and checking its resultcode.
If you must use CopyDirectory, check yourself that the source directory exists.

Why dont you make use of the "InvokeProcess" activity then?
Select the activity, open the Variables tab at the bottom.
Add a variable "ResultCode" of type Int32. This variable will contain the exit code from the copy process.
Add the "InvokeProcess" activity to your workflow.
Open the "InvokeProcess" activity and drop a "WriteBuildMessage" activity inside the Handle Standard Output section.
Set the Importance property to Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High. Set the Message property to stdOutput.
Drop an instance of the WriteBuildError activity to the Handle Error Output section
Set the Message property to errOutput
Now Set "InvokeProcess" properties
FileName: "xcopy"
Agruments: "Source" "Destination" \s \e \y
Result: ResultCode
Check the "ResultCode" value. I use an IF activity and check for the condition "ResultCode <> 0". Within the "THEN" section add a "THROW" activity and add the exception:
"New Exception("Error copying files")
Details here

If copy fails, Set setbuildproperties status to failed in your custom workflow.
<mtbwa1:SetBuildProperties DisplayName=“Set build status failed“ PropertiesToSet=“Status“ Status=“[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]“ />
http://msdn.microsoft.com/en-us/library/bb399143(v=vs.100).aspx

Related

SSIS - File Existence check is not controlling the package task flow properly

There is a pre-existing SSIS package which performs multiple file manipulations based on a source file and often fails when that file is not found at the expected directory. I just want to build some smarts into it so that it will email notification of the missing file, rather than fail.
I have attempted MANY different Script Tasks, using VB, C and SQL, but NOTHING is controlling the process flow consistently. It works sometimes, and when it doesn't work others. I have listed my variables are below --- the top three are all I expected to use, but I added FullPath to simplify things. Unfortunately, that made no change.
My tests: I remove the source files from the directory and execute the package in VS, it DOES call the send email task letting me know the file does not exist. Then I put the files into place and execute the package, it calls the send email task again, as though the file is not there. I am not very good with breakpoints and watch windows, so I put two message boxes into place for Filepath and FileExists -- the Filepath returned IS correct, with the filename, yet the FileExists message box value returned immediately thereafter returns a 0. Note, at the very same time this is telling me it doesn't see the file, I have checked the disk and can see it is there.
Here's the kicker: I've been on this for days and was testing yesterday -- suddenly it works! I put the files into the source directory, it ran the whole process correctly. I removed the files from the source directory, it called the send mail task and completed successfully. I tested both conditions multiple times successfully -- and now it is failing again. I do not understand and have no desire or time to keep testing this file existence check script task that only works intermittently. I even tried today to get the File Properties task that I am hearing so much about (https://archive.codeplex.com/?p=filepropertiestask) but it is incompatible with the current versions of the software. I've tried VS 2019 and SSDT 2017, File Properties is incompatible/unsupported in either. Or, I just don't know how to install it.
Can anyone advise?
Variables -
FileName string, fileName.txt
FilePath string, C:\directory path\
FileExists boolean, False (though I've tried int32, even char N/Y)
FullPath string, C:\Directory path\filename.txt
C Script Task attempts -
public void Main()
{
// TODO: Add your code here
String Filepath = Dts.Variables["User::FilePath"].Value.ToString() + Dts.Variables["User::FileName"].Value.ToString();
if (
File.Exists(Filepath))
{
Dts.Variables["User::FileExists"].Value = 1;
}
else
Dts.Variables["User::FileExists"].Value = 0;
Dts.TaskResult = (int)ScriptResults.Success;
}
OR
//TODO: Add your code here
String Filepath = Dts.Variables["User::FilePath"].Value.ToString() + Dts.Variables["User::FileName"].Value.ToString();
if (
FileExists(Filepath))
{
Dts.Variables["User::FileExists"].Value = 1;
}
MessageBox.Show(Filepath);
MessageBox.Show(Dts.Variables{"User::FileExists"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
or even just as simple as this:
Dts.Variables("FileExists").Value = File.Exists(Dts.Variables("FilePath").Value).ToString
Dts.TaskResult = (int)ScriptResults.Success;
VB Script Task -
Public Sub Main()
' Fill WriteVariable with value from ReadVariable
Dts.Variables("User::FileExists").Value = Dts.Variables("User::FullPath").Value
Dts.TaskResult = ScriptResults.Success
End Sub
Exec SQL Task -
DECLARE
#FilesExist BIT = 0,
#FolderPath VARCHAR(100) = 'C:\directory path\'
DECLARE #Files TABLE ([FileName] VARCHAR(100), Depth INT, [File] INT)
INSERT INTO #Files
EXEC master.sys.xp_dirtree #FolderPath,1,1;
IF EXISTS(
SELECT 1 FROM #Files
WHERE [FileName] = 'fileName.txt'
AND Depth = 1
AND [File] = 1
)
SET #FilesExist = 1
RETURN;
Script Task Precedent constraints:
Evaluation Operation: Expression and Constraint
Value: Success
Expression: #[User::FileExists]==1
Logical AND
Evaluation Operation: Expression and Constraint
Value: Success
Expression: #[User::FileExists]==0
Logical AND
This is a dummied screenshot of my control flow. Where the script task file existence check is the 7th item in the flow. The filename has no date in it. It is always 'filename.txt'. This file is created by the 4th task in the flow by merging other files, and I have just learned that I need to add a similar check here -- but there are multiple files, so I will need to do a wildcard check before the 3rd task in the package as well.
While I like the elegance of Script Tasks, given the current set of tasks, I think you can get by with the out of the box tooling.
Foreach Loop Container
This is the work horse in the solution. It has a built in file enumerator so if your source file is actually SourceFile_YYYYMMDD.txt or something like that, you can just use sourcefile*.txt and it'll find it no problem.
The reason I like this, is that you can put all of your logic inside this container and if the file is found, it's just going to do the expected work. No precursor/successor stuff has to be defined to make it go.
I created another variable called CurrentFile and initialized it to the empty string. This, empty string starting value, is crucial for the success of the package. When the Foreach Loop finds a file, it is going to put the full file name into this variable.
When the package runs and all the file manipulation work is done, if a file was found, the current value of #[User::CurrentFile] is not going to be the empty string. If no file is found, then the value of CurrentFile remains the starting value.
I modified your existing FileExists boolean SSIS Variable to be Expression driven. In the properties, I used the following expression #[User::CurrentFile] != "" If the value of CurrentFile isn't our starting value, then it evaluates to true. Otherwise, it remains false.
Using those two "tricks", that leads us to an SSIS package like the following
I have two paths leading out of the Foreach loop container. Both specify success as the constraint and then we use #[User::FileExists] for the happy path (file found) and the inversion of that !#[User::FileExists] for the not exists path. Put your notification logic inside the container that says "No file found path"
Because I love me some Biml, I am attaching the Biml to create this solution.
Slightly less useful as you need to patch this into an existing package, but you should be able to create a minimum viable package that handles checking and alerting if file not found. And then you can compare a working example to your current implmentation.
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Packages>
<Package Name="so_62505561">
<Variables>
<Variable Name="FileExists" DataType="Boolean" EvaluateAsExpression="true">#[User::CurrentFile] != ""</Variable>
<Variable Name="FileName" DataType="String">so_62505561.txt</Variable>
<Variable Name="FilePath" DataType="String">C:\ssisdata\input</Variable>
<Variable Name="FileSpecification" DataType="String">so_62505561*.txt</Variable>
<Variable Name="FullPath" DataType="String"></Variable>
<Variable Name="CurrentFile" DataType="String"></Variable>
</Variables>
<Tasks>
<ForEachFileLoop Name="FELC Do File Work" FileSpecification="*.txt" ConstraintMode="LinearOnSuccess" Folder="C:\tmp">
<Expressions>
<Expression ExternalProperty="FileSpec">#[User::FileSpecification]</Expression>
<Expression ExternalProperty="Directory">#[User::FilePath]</Expression>
</Expressions>
<VariableMappings>
<VariableMapping Name="0" VariableName="User.CurrentFile" />
</VariableMappings>
<Tasks>
<Container Name="Placeholder for work">
</Container>
</Tasks>
</ForEachFileLoop>
<!-- this is the unhappy path -->
<Container Name="No file found path">
<PrecedenceConstraints>
<Inputs>
<Input EvaluationOperation="ExpressionAndConstraint" EvaluationValue="Success" Expression="!#[User::FileExists]" OutputPathName="FELC Do File Work.Output" />
</Inputs>
</PrecedenceConstraints>
</Container>
<Container Name="File found path">
<PrecedenceConstraints>
<Inputs>
<Input EvaluationOperation="ExpressionAndConstraint" EvaluationValue="Success" Expression="#[User::FileExists]" OutputPathName="FELC Do File Work.Output" />
</Inputs>
</PrecedenceConstraints>
</Container>
</Tasks>
</Package>
</Packages>
</Biml>
Using the script task to test for file existence
Given your assumptions
FileName string, fileName.txt
FilePath string, C:\directory path\
FileExists boolean, False
The Script Task should have FileName and FilePath as read only variables, FileExists is a read/write variable.
// I favor System.IO.Path.Combine for path manipulation as it figures out the correct separator to use
string filepath = System.IO.Path.Combine(Dts.Variables["User::FilePath"].Value.ToString(), Dts.Variables["User::FileName"].Value.ToString());
if (System.IO.File.Exists(filepath))
{
Dts.Variables["User::FileExists"].Value = true;
}
// I favor emitting to the log I can audit it. Also, GUI events are not allowed when run from jobs
// Log the state of all our SSIS variables
bool fireAgain = false;
string message = "{0}::{1} : {2}";
foreach (var item in Dts.Variables)
{
Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, item.Namespace, item.Name, item.Value), string.Empty, 0, ref fireAgain);
}
// Log the file path that was built
Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, "local", "filepath", filepath), string.Empty, 0, ref fireAgain);
Dts.TaskResult = (int)ScriptResults.Success;
At this point, when the script runs, you'll have 4 information events in your log: the state of our 3 SSIS scoped variables and the state of our built path. In the event the downstream bits that depend on #[User::FileExists] are not working as expected, you have all your values in one convenient place.
At this point, the file check script task has exited and the precedent constraints should be flagged as Expression and Constraint using the following combos
Success + #[User::FileExists] (File exists path)
Success + !#[User::FileExists] (Alert path)
Logging note
Firing information events results in the information being emitted in two different locations for the a package run in Visual Studio.
The Output Window and the Progress tab.
Output Window would show something like
SSIS package "C:\Users\bfellows\source\repos\Integration Services Project1\Integration Services Project1\NewPackage.dtsx" starting.
Information: 0x0 at Script Task 1, SCR Echo Back: User::FileExists : False
Information: 0x0 at Script Task 1, SCR Echo Back: User::FileName : fileName.txt
Information: 0x0 at Script Task 1, SCR Echo Back: User::FilePath : C:\directory path\
Information: 0x0 at Script Task 1, SCR Echo Back: local::filepath : C:\directory path\fileName.txt
SSIS package "C:\Users\bfellows\source\repos\Integration Services Project1\Integration Services Project1\NewPackage.dtsx" finished: Success.
whereas the progress tab is a gui element
Final resolution
#sqldba discovered that in the 4th step the VBA was using a local variable FilesExist and not FileExists and since VB is forgiving of non-declared variables, that's where things got "weird"

Custom Uninstall not deleting file in .net Application

I have a settings file created when user run the wpf application.
I have created a custom uninstaller to delete some registry keys related to my app and to delete this setting file.
But my file is not getting deleted.
Here is the code -
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
try
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
if (registryKey.GetValue("TeachingManagementTool") != null)
{
registryKey.DeleteValue("TeachingManagementTool", true);
}
}
if (File.Exists("Setting.ini"))
File.Delete("Setting.ini");
}
catch (Exception ex)
{
MessageBox.Show("Registry Keys exception " + ex.Message);
}
}
I tried Directory.GetCurrentDirectory() to get file names and delte it, but it doesnt work. So I checked this line of code works file.Delete(filename). It delets the specified file. So it should delete the file during uninstall as its in the same folder.
At the end I should say- I tried 2-3 different ways to access that file and delete it during uninstallation. but Its not delteting and throwing error some times and sometimes no exception at all.
The exception was related to Access to SysWOW64\AdvanceInstaller is
denied
FYI - MY App has <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> already.
I tried solutions available on StackOverflow but its not working So I needed to ask a new question. So please let me know where I am mistaking. I am sure it is something very minor that I might be missing here
Advanced Installer: So you are using Advanced Installer? In the Files and Folders view, select the destination folder in question. In the right pane, right click inside the folder where the file to remove resides. Do you see "New File Operation"? Select "File Removal" and configure options.
Remember to set the options properly. In particular "Remove On". Select on "Component Uninstall".

How to combine "sonar.cpd.exclusions" with the parameters in SONARQUBE Server?

According to the structure of our project, if I want to exclude the .cs files from PY.Models \ Module1, PY.Entities \ Module1, PY.Entities \ Module2, PY.Entities \ Module3 and that "PY. Repository.ModuleN "are not going to be excluded ?. How to combine "sonar.cpd.exclusions" with the parameters in SONARQUBE Server?
D:\MYCOMPANY \ MYPROJECT\00_Transversal\PY.Models\PY.Models\Modulo1--
D:\MYCOMPANY\MYPROJECT\00_Transversal\PY.Models\PY.Models\Modulo2
D:\MYCOMPANY\MYPROJECT\00_Transversal\PY.Models\PY.Models\Modulo3
D:\MYCOMPANY \ MYPROJECT \01_Data\PY.Entities\PY.Entities\Module1--
D:\MYCOMPANY \ MYPROJECT \01_Data\PY.Entities\PY.Entities\Module2--
D:\MYCOMPANY \ MYPROJECT \01_Data\PY.Entities\PY.Entities\Module3--
D:\MYCOMPANY\MYPROJECT\01_Data\PY.Repository.Module1
D:\MYCOMPANY\MYPROJECT\01_Data\PY.Repository.Module2
D:\MYCOMPANY\MYPROJECT\01_Data\PY.Repository.Module3
Configuration On the SONARQUBE-Duplications Tab-page Server
To exclude a file or directory entirely from analysis, go to Administration > General Settings > Analysis Scope > Files and set sonar.exclusions using patterns* to describe what should be left out.
To exclude a file or directory from duplication detection, you want to set sonar.cpd.exclusions, as you surmised. Again, use a pattern* for this value.
Regarding whether to set this in analysis parameters or the server, I'd personally set it server-side. Just cleaner, IMO.
Recognized wildcards: * 0-n char; ** 0-n directories; ? any single character
The properties are set via ItemGroup in each .csproj file, this way:
<ItemGroup>
<SonarQubeSetting Include="sonar.cpd.exclusions">
<Value>Models/**/*.cs</Value>
</SonarQubeSetting>
</ItemGroup>

Microsoft Edge Delete History and Cookies Programmatically

Is there any way to delete history & cookies of Microsoft Edge browser using VBScript or .net?
Like Internet Explorer, deleting the history form "%AppData%\Local\Microsoft\Windows\History" folder or Rundll32 commands?
Rundll32 commands
Delete Cookies:
rundll32.exe,InetCpl.cpl,ClearMyTracksByProcess 2
Delete History:
rundll32.exe,InetCpl.cpl,ClearMyTracksByProcess 1
Edit:
Found an solution for clearing cookie http://winhelp2002.mvps.org/cookies.htm. Deleting files from following 4 folders will clear cookies without affecting history and cache.
1. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3‌​d8bbwe\AC\#!001\MicrosoftEdge\Cookies
2. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3‌​d8bbwe\AC\#!002\MicrosoftEdge\Cookies
3. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3‌​d8bbwe\AC\#!121\MicrosoftEdge\Cookies
4. \Users\user name\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3‌​d8bbwe\AC\MicrosoftEdge\Cookies
Still need help to clear history without affecting cookie and cache
This is not Safe But First You need To Close Microsoft Edge browser, Then you should delete All Sub_Folders and Files are in :
"C:\Users\[username]\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
Change [username] with your own Windows Username.
VB Script Code :
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("C:\Users\[username]\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe")
for each f in folder.Files
On Error Resume Next
name = f.name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & Name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & Name
End If
On Error GoTo 0
Next
For Each f In folder.SubFolders
On Error Resume Next
name = f.name
f.Delete True
If Err Then
WScript.Echo "Error deleting:" & Name & " - " & Err.Description
Else
WScript.Echo "Deleted:" & Name
End If
On Error GoTo 0
Next
Note : Run This Source AS ADMIN
Another Way :
Call WshShell.Run("powershell -command Get-AppXPackage -AllUsers -Name Microsoft.MicrosoftEdge | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml” -Verbose}")
RUN AS ADMIN TOO

How to get the (.lnk) shortcut filepath in a program which started by the shortcut?

I have a c# program which open *.postfix file.
If a user runs a (.lnk)shortcut which points to my type of file, my program will open the target.
So, how could my program know it is started by a (.lnk)shortcut (and get it's file path)?
In some circumstances,i need to replace the .lnk file.
Thanks!
Edited
First, thanks to guys who answered my question.
By following #Anders answer, i find out my problem lays here.
I made some changes to windows registry, so browser knows to throw customized protocol string to certain program.
some thing like this..
[InternetShortcut]
URL=myProtocol://abcdefg.....
That's maybe why i lost lpTitle. :(
I'm going to try this way:
Whenever my program invoked, of course fed with %1, program checks current opened explorer(Window), and try to get it's current path with IWebBrowserApp. With that path and desktop of course, scan and analyze *.lnk to determine which one to replace.
I think this will probably work, but not be sure. I will try.
continued
In native code you can call GetStartupInfo, if the STARTF_TITLEISLINKNAME bit is set in STARTUPINFO.dwFlags then the path to the .lnk is in STARTUPINFO.lpTitle. I don't know if there is a .NET way to get this info, you probably have to P/Invoke...
You don't. There's no way to do it. End of story.
So this has been brought to my attention due to a recent downvote. There's an accepted answer showing an idea that gets the path to the launching shortcut most of the time. However my answer is to the whole. OP wants the link to the shortcut so he can change it. That is what can't be done most of the time.
Most likely case is the shortcut file exists in the start menu but is unwritable. However other cases involve the shortcut coming from another launching application that didn't even read it from a disk but from a database (I've seen a lot of corporate level restricted application launch tools). I also have a program that launches programs from shortcuts not via IShellLink but by parsing the .lnk file (because it must not start COM for reasons) and launching the program contained. It doesn't pass STARTF_TITLEISLINKNAME because it's passing an actual title.
If you're using Visual Studio Setup Project to build an installer and do the file type association, you should follow these instructions http://www.dreamincode.net/forums/topic/58005-file-associations-in-visual-studio/
Open up your solution in Visual studio.
Add a Setup Project to your solution by file , add project,New project, Setup & Deployment projects,Setup project
Right-click on your setup project in the "Solution Explorer" window,Select view,then select file types.
you'll see the "file types" window displayed in Visual studio.At the top of the window will be "File types on target machine"
Right-click on "File types on target machine".the menu will pop up with Add "file type" Click on this.
you'll see "New document Type#1" added,and "&open"underneath it.
The "new document type#1" can be anything you want - change it to something descriptive.although the user never sees this,never use something common- be as unique as possible,Because you can overlay current file associations without even realizing it.For example,you might think"pngfile" might be a useful name- but using that will now send all"*.png" files to your application,instead of to an image viewer.A good practice maybe "YourCompantName.Filetype",where your company name is your name of your company's name, and "Filetype" is a descriptive text of your file.
In the "properties" window for your new type,you will need to change a few properties.:
Command:Change to the application that you want to run.If you click on the "..." and you will proberly want to locate and use the "primary Output..." File
Description: This is the description of the file type(if it doesn't describe it's self"
Extensions:This your list of extensions for you chosen Program.Separate each one with a ","
Icon:This will associate the icon with your file type,This shows up in the window explorer.
Now we move to that "&open ".This is an action that is available if your right-click on the file.The default action("&Open" is currently set as the default) is what happens when you double click on the file.Right click on your "New document type#1" to add actions,but for the moment,lets define our "&open" action
Click on "&Open".You will see in the properties window "Name","Arguments","Verbs". Verb is hidden from the user,but is the key that is stored in the registry.Leave it same as the name,But without the "&".The default for"Arguments" is "%1",Which means to pass the full path and filename to your application.You can add other stuff here as well,if you need to pass flags to your application to do special stuff.All this infomaton is getting passed to your application on the command line,so you'll need to be familiar with the "Environment.CommandLine" object.
If you need to set a different action as your default,just right click on the action and "set as default"
Basically, you'll pass the file path as an argument to your program. Then if it's a console application or Windows Forms , you should check the arguments in Program.Main
static void Main(string[] args)
{
//if file association done with Arguments %1 as per forum post above
//you file path should be in args[0]
string filePath = null;
if(args != null && args.Length > 0)
filePath = args[0];
}
For a WPF application you'll need to handle that in the StartUp event for your Application
void App_Startup(object sender, StartupEventArgs e)
{
string filePath = null;
if ((e.Args != null) && (e.Args.Length > 0))
{
filePath = e.Args[0];
}
}

Categories

Resources