Related
Suppose I'm working with the following C snippet:
void inc(int *num) {*num++;}
void dec(int *num) {*num--;}
void f(int var) {
inc(&var);
dec(&var);
}
By using a static analyzer, I want to be able to tell if the value of var didn't change during the function's execution. I know I have to keep its state on my own (that's the point of writing a Clang checker), but I'm having troubles getting a unique reference of this variable.
For example: if I use the following API
void MySimpleChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol();
}
I'd expect it to return a pointer to this symbol's representation in my checker's context. However, I always get 0 into MyArg by using it this way. This happens for both inc and dec functions in the pre and post callbacks.
What am I missing here? What concepts did I get wrong?
Note: I'm currently reading the Clang CFE Internals Manual and I've read the excellent How to Write a Checker in 24 Hours material. I still couldn't find my answer so far.
Interpretation of question
Specifically, you want to count the calls to inc and dec applied to each variable and report when they do not balance for some path in a function.
Generally, you want to know how to associate an abstract value, here a number, with a program variable, and be able to update and query that value along each execution path.
High-level answer
Whereas the tutorial checker SimpleStreamChecker.cpp associates an abstract value with the value stored in a variable, here we want associate an abstract value with the variable itself. That is what IteratorChecker.cpp does when tracking containers, so I based my solution on it.
Within the static analyzer's abstract state, each variable is represented by a MemRegion object. So the first step is to make a map where MemRegion is the key:
REGISTER_MAP_WITH_PROGRAMSTATE(TrackVarMap, MemRegion const *, int)
Next, when we have an SVal that corresponds to a pointer to a variable, we can use SVal::getAsRegion to get the corresponding MemRegion. For instance, given a CallEvent, call, with a first argument that is a pointer, we can do:
if (MemRegion const *region = call.getArgSVal(0).getAsRegion()) {
to get the region that the pointer points at.
Then, we can access our map using that region as its key:
state = state->set<TrackVarMap>(region, newValue);
Finally, in checkDeadSymbols, we use SymbolReaper::isLiveRegion to detect when a region (variable) is going out of scope:
const TrackVarMapTy &Map = state->get<TrackVarMap>();
for (auto const &I : Map) {
MemRegion const *region = I.first;
int delta = I.second;
if (SymReaper.isLiveRegion(region) || (delta==0))
continue; // Not dead, or unchanged; skip.
Complete example
To demonstrate, here is a complete checker that reports unbalanced use of inc and dec:
// TrackVarChecker.cpp
// https://stackoverflow.com/questions/23448540/how-to-keep-track-of-a-variable-with-clangs-static-analyzer
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
using namespace clang;
using namespace ento;
namespace {
class TrackVarChecker
: public Checker< check::PostCall,
check::DeadSymbols >
{
mutable IdentifierInfo *II_inc, *II_dec;
mutable std::unique_ptr<BuiltinBug> BT_modified;
public:
TrackVarChecker() : II_inc(nullptr), II_dec(nullptr) {}
void checkPostCall(CallEvent const &Call, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
};
} // end anonymous namespace
// Map from memory region corresponding to a variable (that is, the
// variable itself, not its current value) to the difference between its
// current and original value.
REGISTER_MAP_WITH_PROGRAMSTATE(TrackVarMap, MemRegion const *, int)
void TrackVarChecker::checkPostCall(CallEvent const &call, CheckerContext &C) const
{
const FunctionDecl *FD = dyn_cast<FunctionDecl>(call.getDecl());
if (!FD || FD->getKind() != Decl::Function) {
return;
}
ASTContext &Ctx = C.getASTContext();
if (!II_inc) {
II_inc = &Ctx.Idents.get("inc");
}
if (!II_dec) {
II_dec = &Ctx.Idents.get("dec");
}
if (FD->getIdentifier() == II_inc || FD->getIdentifier() == II_dec) {
// We expect the argument to be a pointer. Get the memory region
// that the pointer points at.
if (MemRegion const *region = call.getArgSVal(0).getAsRegion()) {
// Increment the associated value, creating it first if needed.
ProgramStateRef state = C.getState();
int delta = (FD->getIdentifier() == II_inc)? +1 : -1;
int const *curp = state->get<TrackVarMap>(region);
int newValue = (curp? *curp : 0) + delta;
state = state->set<TrackVarMap>(region, newValue);
C.addTransition(state);
}
}
}
void TrackVarChecker::checkDeadSymbols(
SymbolReaper &SymReaper, CheckerContext &C) const
{
ProgramStateRef state = C.getState();
const TrackVarMapTy &Map = state->get<TrackVarMap>();
for (auto const &I : Map) {
// Check for a memory region (variable) going out of scope that has
// a non-zero delta.
MemRegion const *region = I.first;
int delta = I.second;
if (SymReaper.isLiveRegion(region) || (delta==0)) {
continue; // Not dead, or unchanged; skip.
}
//llvm::errs() << region << " dead with delta " << delta << "\n";
if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
if (!BT_modified) {
BT_modified.reset(
new BuiltinBug(this, "Delta not zero",
"Variable changed from its original value."));
}
C.emitReport(llvm::make_unique<BugReport>(
*BT_modified, BT_modified->getDescription(), N));
}
}
}
void ento::registerTrackVarChecker(CheckerManager &mgr) {
mgr.registerChecker<TrackVarChecker>();
}
bool ento::shouldRegisterTrackVarChecker(const LangOptions &LO) {
return true;
}
To hook this in to the rest of Clang, add entries to:
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td and
clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
Example input to test it:
// trackvar.c
// Test for TrackVarChecker.
// The behavior of these functions is hardcoded in the checker.
void inc(int *num);
void dec(int *num);
void call_inc(int var) {
inc(&var);
} // reported
void call_inc_dec(int var) {
inc(&var);
dec(&var);
} // NOT reported
void if_inc(int var) {
if (var > 2) {
inc(&var);
}
} // reported
void indirect_inc(int val) {
int *p = &val;
inc(p);
} // reported
Sample run:
$ gcc -E -o trackvar.i trackvar.c
$ ~/bld/llvm-project/build/bin/clang -cc1 -analyze -analyzer-checker=alpha.core.TrackVar trackvar.i
trackvar.c:10:1: warning: Variable changed from its original value
}
^
trackvar.c:21:1: warning: Variable changed from its original value
}
^
trackvar.c:26:1: warning: Variable changed from its original value
}
^
3 warnings generated.
I think you missed the check that this call event is a call to your function inc/dec. You should have something like
void MySimpleChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
const IdentifierInfo* callee = Call.getCalleeIdentifier();
if (callee->getName().str() == "inc" || callee->getName().str() == "dec")
SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol();
}
I have a problem about the mbeans. I have created a simple mbean and I have registered it on the default mBeanServer that is run (Via eclipse or java -jar mbean.jar) and in the same process if I try to fouund the mbean registered with a simple query:
for (ObjectInstance instance : mbs.queryMBeans(ObjectNameMbean, null)) {
System.out.println(instance.toString());
}
the query retuerns my mbean, but if I start another process and try to search this mbean registered the mbeas is not found! why?
The approch is : (Process that is running)
public static void main(String[] args) throws Exception
{
MBeanServer mbeanServer =ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName(ObjectNameMbean);
Simple simple = new Simple (1, 0);
mbeanServer.registerMBean(simple, objectName);
while (true)
{
wait (Is this necessary?)
}
}
So this is the first process that is running (that has the only pourpose to registry the mbean, because there is another process that want to read these informations.
So I start another process to search this mbean but nothing.
I 'm not using jboss but the local Java virtual Machine but my scope is to deploy this simple application in one ejb (autostart) and another ejb will read all informations.
All suggestions are really apprecciated.
This example should be more useful :
Object Hello:
public class Hello implements HelloMBean {
public void sayHello() {
System.out.println("hello, world");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return this.name;
}
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
this.cacheSize = size;
System.out.println("Cache size now " + this.cacheSize);
}
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
}
Interface HelloBean (implemented by Hello)
public interface HelloMBean {
public void sayHello();
public int add(int x, int y);
public String getName();
public int getCacheSize();
public void setCacheSize(int size);
}
Simple Main
import java.lang.management.ManagementFactory;
import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Main {
static Logger aLog = Logger.getLogger("MBeanTest");
public static void main(String[] args) {
try{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("ApplicationDomain:type=Hello");
Hello mbean = new Hello();
mbs.registerMBean(mbean, name);
// System.out.println(mbs.getAttribute(name, "Name"));
aLog.info("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
}
catch(Exception x){
x.printStackTrace();
aLog.info("exception");
}
}
}
So now I have exported this project as jar file and run it as "java -jar helloBean.jar" and by eclipse I have modified the main class to read informations of this read (Example "Name" attribute) by using the same objectname used to registry it .
Main to read :
public static void main(String[] args) {
try{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("ApplicationDomain:type=Hello");
System.out.println(mbs.getAttribute(name, "Name"));
}
catch(Exception x){
x.printStackTrace();
aLog.info("exception");
}
}
But nothing, the bean is not found.
Project link : here!
Any idea?
I suspect the issue here is that you have multiple MBeanServer instances. You did not mention how you acquired the MBeanServer in each case, but in your second code sample, you are creating a new MBeanServer instance which may not be the same instance that other threads are reading from. (I assume this is all in one JVM...)
If you are using the platform agent, I recommend you acquire the MBeanServer using the ManagementFactory as follows:
MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer() ;
That way, you will always get the same MBeanServer instance.
This is related to TFS 2010 Build System. Within our build workflow we set a couple of environment variables using the SetEnvironmentVariable method of System.Environment class. I have confirmed that this environment variable gets set properly on the build server and that it gets set as a system wide environment variable.
The problem is that when MSBuild gets invoked within this WF and it compiles the solutions, our post build events which tries to read this environment variable fail as they are unable to see this environment variable.
Is there a way to force MSBuild to reload environment variables or force a running WF to reload environment variables? My suspicion is that even though WF creates this variable, it does not refresh its Environment state and hence can not see the variable. Further since the WF invokes MSBuild, it passes the same environment state to MSBuild which does ont contain this variable.
Update
Stick the following code in Visual Studio and run it. The delay to SendMessageTimeOut is 10 second so be patient.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace EnvironmentVarTest
{
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool
SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
out int lpdwResult
);
public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;
static void Main(string[] args)
{
Program p = new Program();
string environmentVariableValue = DateTime.Now.ToLongTimeString().Replace(":", String.Empty);
Console.WriteLine("On the CMD window that opens up after about 10 seconds, if you type %samplevar% and hit Enter, you should see: " + environmentVariableValue);
p.SetEnvironmentVariable(environmentVariableValue);
RefreshProcessVars();
p.ReadEnvironmentVariable();
p.StartCMD();
Console.ReadLine();
}
void SetEnvironmentVariable(string value)
{
System.Environment.SetEnvironmentVariable("samplevar", value, EnvironmentVariableTarget.Machine);
}
static void RefreshProcessVars()
{
int result;
bool callresult = SendMessageTimeout(
(System.IntPtr)HWND_BROADCAST,
WM_SETTINGCHANGE,
0,
"Environment",
SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
10000,
out result);
if (!callresult || result == 0)
{
int lasterror = Marshal.GetLastWin32Error();
Win32Exception winex = new Win32Exception(lasterror);
Console.WriteLine("Exception happened while calling SendMessageTimeOut. The exception message is " + winex.Message);
}
}
void ReadEnvironmentVariable()
{
var x = System.Environment.GetEnvironmentVariable("samplevar", EnvironmentVariableTarget.Machine);
}
void StartCMD()
{
Process.Start("cmd.exe");
}
}
}
Unfortunately, because the MSBuild process is passed a cached version of the environment variables when it's started up, the command-line functionality of that process will not be able to see the updated values. The best bet you've got, in my opinion, is to either change that variable in the post-build event or store the value in a medium that you can read from the post-build event.
Update
Okay, so the statement below (which can be found here) I think explains where the environment variables are coming from and why you're not getting an updated version in MSBuild.
By default, a child process inherits the environment variables of its parent process.
So, two can play at that game, let's just broadcast that a change has occurred and see if that will take care of it for us. Below is the code that should do that for you.
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool
SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
out int lpdwResult
);
public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;
int result;
SendMessageTimeout(
(System.IntPtr)HWND_BROADCAST,
WM_SETTINGCHANGE,
0,
"Environment",
SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
SomeTimeoutValue,
out result);
Is there a set of constants in the framework for all the standard content types?
Taking it as a resounding no, I wrote my own. That's what Sundays were made for.
///<summary>Used to denote the encoding necessary for files containing JavaScript source code. The alternative MIME type for this file type is text/javascript.</summary>
public const string ApplicationXJavascript = "application/x-javascript";
///<summary>24bit Linear PCM audio at 8-48kHz, 1-N channels; Defined in RFC 3190</summary>
public const string AudioL24 = "audio/L24";
///<summary>Adobe Flash files for example with the extension .swf</summary>
public const string ApplicationXShockwaveFlash = "application/x-shockwave-flash";
///<summary>Arbitrary binary data.[5] Generally speaking this type identifies files that are not associated with a specific application. Contrary to past assumptions by software packages such as Apache this is not a type that should be applied to unknown files. In such a case, a server or application should not indicate a content type, as it may be incorrect, but rather, should omit the type in order to allow the recipient to guess the type.[6]</summary>
public const string ApplicationOctetStream = "application/octet-stream";
///<summary>Atom feeds</summary>
public const string ApplicationAtomXml = "application/atom+xml";
///<summary>Cascading Style Sheets; Defined in RFC 2318</summary>
public const string TextCss = "text/css";
///<summary>commands; subtype resident in Gecko browsers like Firefox 3.5</summary>
public const string TextCmd = "text/cmd";
///<summary>Comma-separated values; Defined in RFC 4180</summary>
public const string TextCsv = "text/csv";
///<summary>deb (file format), a software package format used by the Debian project</summary>
public const string ApplicationXDeb = "application/x-deb";
///<summary>Defined in RFC 1847</summary>
public const string MultipartEncrypted = "multipart/encrypted";
///<summary>Defined in RFC 1847</summary>
public const string MultipartSigned = "multipart/signed";
///<summary>Defined in RFC 2616</summary>
public const string MessageHttp = "message/http";
///<summary>Defined in RFC 4735</summary>
public const string ModelExample = "model/example";
///<summary>device-independent document in DVI format</summary>
public const string ApplicationXDvi = "application/x-dvi";
///<summary>DTD files; Defined by RFC 3023</summary>
public const string ApplicationXmlDtd = "application/xml-dtd";
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/ecmascript but with looser processing rules) It is not accepted in IE 8 or earlier - text/javascript is accepted but it is defined as obsolete in RFC 4329. The "type" attribute of the <script> tag in HTML5 is optional and in practice omitting the media type of JavaScript programs is the most interoperable solution since all browsers have always assumed the correct default even before HTML5.</summary>
public const string ApplicationJavascript = "application/javascript";
///<summary>ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to application/javascript but with stricter processing rules)</summary>
public const string ApplicationEcmascript = "application/ecmascript";
///<summary>EDI EDIFACT data; Defined in RFC 1767</summary>
public const string ApplicationEdifact = "application/EDIFACT";
///<summary>EDI X12 data; Defined in RFC 1767</summary>
public const string ApplicationEdiX12 = "application/EDI-X12";
///<summary>Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MessagePartial = "message/partial";
///<summary>Email; EML files, MIME files, MHT files, MHTML files; Defined in RFC 2045 and RFC 2046</summary>
public const string MessageRfc822 = "message/rfc822";
///<summary>Extensible Markup Language; Defined in RFC 3023</summary>
public const string TextXml = "text/xml";
///<summary>Extensible Markup Language; Defined in RFC 3023</summary>
public const string ApplicationXml = "application/xml";
///<summary>Flash video (FLV files)</summary>
public const string VideoXFlv = "video/x-flv";
///<summary>GIF image; Defined in RFC 2045 and RFC 2046</summary>
public const string ImageGif = "image/gif";
///<summary>GoogleWebToolkit data</summary>
public const string TextXGwtRpc = "text/x-gwt-rpc";
///<summary>Gzip</summary>
public const string ApplicationXGzip = "application/x-gzip";
///<summary>HTML; Defined in RFC 2854</summary>
public const string TextHtml = "text/html";
///<summary>ICO image; Registered[9]</summary>
public const string ImageVndMicrosoftIcon = "image/vnd.microsoft.icon";
///<summary>IGS files, IGES files; Defined in RFC 2077</summary>
public const string ModelIges = "model/iges";
///<summary>IMDN Instant Message Disposition Notification; Defined in RFC 5438</summary>
public const string MessageImdnXml = "message/imdn+xml";
///<summary>JavaScript Object Notation JSON; Defined in RFC 4627</summary>
public const string ApplicationJson = "application/json";
///<summary>JavaScript Object Notation (JSON) Patch; Defined in RFC 6902</summary>
public const string ApplicationJsonPatch = "application/json-patch+json";
///<summary>JavaScript - Defined in and obsoleted by RFC 4329 in order to discourage its usage in favor of application/javascript. However,text/javascript is allowed in HTML 4 and 5 and, unlike application/javascript, has cross-browser support. The "type" attribute of the <script> tag in HTML5 is optional and there is no need to use it at all since all browsers have always assumed the correct default (even in HTML 4 where it was required by the specification).</summary>
[Obsolete]
public const string TextJavascript = "text/javascript";
///<summary>JPEG JFIF image; Associated with Internet Explorer; Listed in ms775147(v=vs.85) - Progressive JPEG, initiated before global browser support for progressive JPEGs (Microsoft and Firefox).</summary>
public const string ImagePjpeg = "image/pjpeg";
///<summary>JPEG JFIF image; Defined in RFC 2045 and RFC 2046</summary>
public const string ImageJpeg = "image/jpeg";
///<summary>jQuery template data</summary>
public const string TextXJqueryTmpl = "text/x-jquery-tmpl";
///<summary>KML files (e.g. for Google Earth)</summary>
public const string ApplicationVndGoogleEarthKmlXml = "application/vnd.google-earth.kml+xml";
///<summary>LaTeX files</summary>
public const string ApplicationXLatex = "application/x-latex";
///<summary>Matroska open media format</summary>
public const string VideoXMatroska = "video/x-matroska";
///<summary>Microsoft Excel 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentSpreadsheetmlSheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
///<summary>Microsoft Excel files</summary>
public const string ApplicationVndMsExcel = "application/vnd.ms-excel";
///<summary>Microsoft Powerpoint 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentPresentationmlPresentation = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
///<summary>Microsoft Powerpoint files</summary>
public const string ApplicationVndMsPowerpoint = "application/vnd.ms-powerpoint";
///<summary>Microsoft Word 2007 files</summary>
public const string ApplicationVndOpenxmlformatsOfficedocumentWordprocessingmlDocument = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
///<summary>Microsoft Word files[15]</summary>
public const string ApplicationMsword = "application/msword";
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MultipartAlternative = "multipart/alternative";
///<summary>MIME Email; Defined in RFC 2045 and RFC 2046</summary>
public const string MultipartMixed = "multipart/mixed";
///<summary>MIME Email; Defined in RFC 2387 and used by MHTML (HTML mail)</summary>
public const string MultipartRelated = "multipart/related";
///<summary>MIME Webform; Defined in RFC 2388</summary>
public const string MultipartFormData = "multipart/form-data";
/// <summary>Body contains a URL-encoded query string as per RFC 1867</summary>
public const string ApplicationWwwFormUrlEncoded = "application/x-www-form-urlencoded";
///<summary>Mozilla XUL files</summary>
public const string ApplicationVndMozillaXulXml = "application/vnd.mozilla.xul+xml";
///<summary>MP3 or other MPEG audio; Defined in RFC 3003</summary>
public const string AudioMpeg = "audio/mpeg";
///<summary>MP4 audio</summary>
public const string AudioMp4 = "audio/mp4";
///<summary>MP4 video; Defined in RFC 4337</summary>
public const string VideoMp4 = "video/mp4";
///<summary>MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046</summary>
public const string VideoMpeg = "video/mpeg";
///<summary>MSH files, MESH files; Defined in RFC 2077, SILO files</summary>
public const string ModelMesh = "model/mesh";
///<summary>mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046</summary>
public const string AudioBasic = "audio/basic";
///<summary>Ogg Theora or other video (with audio); Defined in RFC 5334</summary>
public const string VideoOgg = "video/ogg";
///<summary>Ogg Vorbis, Speex, Flac and other audio; Defined in RFC 5334</summary>
public const string AudioOgg = "audio/ogg";
///<summary>Ogg, a multimedia bitstream container format; Defined in RFC 5334</summary>
public const string ApplicationOgg = "application/ogg";
///<summary>OP</summary>
public const string ApplicationXopXml = "application/xop+xml";
///<summary>OpenDocument Graphics; Registered[14]</summary>
public const string ApplicationVndOasisOpendocumentGraphics = "application/vnd.oasis.opendocument.graphics";
///<summary>OpenDocument Presentation; Registered[13]</summary>
public const string ApplicationVndOasisOpendocumentPresentation = "application/vnd.oasis.opendocument.presentation";
///<summary>OpenDocument Spreadsheet; Registered[12]</summary>
public const string ApplicationVndOasisOpendocumentSpreadsheet = "application/vnd.oasis.opendocument.spreadsheet";
///<summary>OpenDocument Text; Registered[11]</summary>
public const string ApplicationVndOasisOpendocumentText = "application/vnd.oasis.opendocument.text";
///<summary>p12 files</summary>
public const string ApplicationXPkcs12 = "application/x-pkcs12";
///<summary>p7b and spc files</summary>
public const string ApplicationXPkcs7Certificates = "application/x-pkcs7-certificates";
///<summary>p7c files</summary>
public const string ApplicationXPkcs7Mime = "application/x-pkcs7-mime";
///<summary>p7r files</summary>
public const string ApplicationXPkcs7Certreqresp = "application/x-pkcs7-certreqresp";
///<summary>p7s files</summary>
public const string ApplicationXPkcs7Signature = "application/x-pkcs7-signature";
///<summary>Portable Document Format, PDF has been in use for document exchange on the Internet since 1993; Defined in RFC 3778</summary>
public const string ApplicationPdf = "application/pdf";
///<summary>Portable Network Graphics; Registered,[8] Defined in RFC 2083</summary>
public const string ImagePng = "image/png";
///<summary>PostScript; Defined in RFC 2046</summary>
public const string ApplicationPostscript = "application/postscript";
///<summary>QuickTime video; Registered[10]</summary>
public const string VideoQuicktime = "video/quicktime";
///<summary>RAR archive files</summary>
public const string ApplicationXRarCompressed = "application/x-rar-compressed";
///<summary>RealAudio; Documented in RealPlayer Customer Support Answer 2559</summary>
public const string AudioVndRnRealaudio = "audio/vnd.rn-realaudio";
///<summary>Resource Description Framework; Defined by RFC 3870</summary>
public const string ApplicationRdfXml = "application/rdf+xml";
///<summary>RSS feeds</summary>
public const string ApplicationRssXml = "application/rss+xml";
///<summary>SOAP; Defined by RFC 3902</summary>
public const string ApplicationSoapXml = "application/soap+xml";
///<summary>StuffIt archive files</summary>
public const string ApplicationXStuffit = "application/x-stuffit";
///<summary>SVG vector image; Defined in SVG Tiny 1.2 Specification Appendix M</summary>
public const string ImageSvgXml = "image/svg+xml";
///<summary>Tag Image File Format (only for Baseline TIFF); Defined in RFC 3302</summary>
public const string ImageTiff = "image/tiff";
///<summary>Tarball files</summary>
public const string ApplicationXTar = "application/x-tar";
///<summary>Textual data; Defined in RFC 2046 and RFC 3676</summary>
public const string TextPlain = "text/plain";
///<summary>TrueType Font No registered MIME type, but this is the most commonly used</summary>
public const string ApplicationXFontTtf = "application/x-font-ttf";
///<summary>vCard (contact information); Defined in RFC 6350</summary>
public const string TextVcard = "text/vcard";
///<summary>Vorbis encoded audio; Defined in RFC 5215</summary>
public const string AudioVorbis = "audio/vorbis";
///<summary>WAV audio; Defined in RFC 2361</summary>
public const string AudioVndWave = "audio/vnd.wave";
///<summary>Web Open Font Format; (candidate recommendation; use application/x-font-woff until standard is official)</summary>
public const string ApplicationFontWoff = "application/font-woff";
///<summary>WebM Matroska-based open media format</summary>
public const string VideoWebm = "video/webm";
///<summary>WebM open media format</summary>
public const string AudioWebm = "audio/webm";
///<summary>Windows Media Audio Redirector; Documented in Microsoft help page</summary>
public const string AudioXMsWax = "audio/x-ms-wax";
///<summary>Windows Media Audio; Documented in Microsoft KB 288102</summary>
public const string AudioXMsWma = "audio/x-ms-wma";
///<summary>Windows Media Video; Documented in Microsoft KB 288102</summary>
public const string VideoXMsWmv = "video/x-ms-wmv";
///<summary>WRL files, VRML files; Defined in RFC 2077</summary>
public const string ModelVrml = "model/vrml";
///<summary>X3D ISO standard for representing 3D computer graphics, X3D XML files</summary>
public const string ModelX3DXml = "model/x3d+xml";
///<summary>X3D ISO standard for representing 3D computer graphics, X3DB binary files</summary>
public const string ModelX3DBinary = "model/x3d+binary";
///<summary>X3D ISO standard for representing 3D computer graphics, X3DV VRML files</summary>
public const string ModelX3DVrml = "model/x3d+vrml";
///<summary>XHTML; Defined by RFC 3236</summary>
public const string ApplicationXhtmlXml = "application/xhtml+xml";
///<summary>ZIP archive files; Registered[7]</summary>
public const string ApplicationZip = "application/zip";
Update
Stumbled upon this great resource today.
https://www.iana.org/assignments/media-types/media-types.xhtml
Update 22-03-2020
As Jon and James White mentioned on comments, you can check:
System.Net.Mime.MediaTypeNames
You could use:
System.Net.Mime.MediaTypeNames.Application
System.Net.Mime.MediaTypeNames.Image
System.Net.Mime.MediaTypeNames.Text
For example, System.Net.Mime.MediaTypeNames.Image.Gif is equal to "image/gif".
Here is the complete list of default content type constants in .NET Framework base class library (BCL). You will have to add reference to System.Net.Http.dll in your project to use these constants.
System.Net.Mime.MediaTypeNames.Application.Octet for application/octet-stream
System.Net.Mime.MediaTypeNames.Application.Pdf for application/pdf
System.Net.Mime.MediaTypeNames.Application.Rtf for application/rtf
System.Net.Mime.MediaTypeNames.Application.Soap for application/soap+xml
System.Net.Mime.MediaTypeNames.Application.Zip for application/zip
System.Net.Mime.MediaTypeNames.Image.Gif for image/gif
System.Net.Mime.MediaTypeNames.Image.Jpeg for image/jpeg
System.Net.Mime.MediaTypeNames.Image.Tiff for image/tiff
System.Net.Mime.MediaTypeNames.Text.Html for text/html
System.Net.Mime.MediaTypeNames.Text.Plain for text/plain
System.Net.Mime.MediaTypeNames.Text.RichText for text/richtext
System.Net.Mime.MediaTypeNames.Text.Xml for text/xml
Update[12-Aug-2021]:
A new set of constants are now available in System.Net.Mime namespace. This namespace is part of System.Net.Mail.dll which is referenced by default whenever you create a new project targeting .NET v5. This DLL is part of .NET v5 (erstwhile .NET Core v5) release.
MediaTypeNames.Application.Json
MediaTypeNames.Application.Octet
MediaTypeNames.Application.Pdf
MediaTypeNames.Application.Rtf
MediaTypeNames.Application.Soap
MediaTypeNames.Application.Xml
MediaTypeNames.Application.Zip
MediaTypeNames.Image.Gif
MediaTypeNames.Image.Jpeg
MediaTypeNames.Image.Tiff
MediaTypeNames.Text.Html
MediaTypeNames.Text.Plain
MediaTypeNames.Text.RichText
MediaTypeNames.Text.Xml
Note: .NET v5 is not a new release of .NET Framework. Instead it is the next major release of .NET following .NET Core v3.1. .NET is new name of .NET Core. Core branding has been removed.
In the new ASP.NET Core MimeMapping can be used with the filename:
MimeMapping.GetMimeMapping("1.jpg")
Should return image/jpeg.
All the mappings can be found here and it is also possible to add your own (see e.g. this answer).
Here's the official on going list if interested
http://www.iana.org/assignments/media-types/media-types.xhtml
Please also check this amazing solution in below link (section "Using a static MIME Type Map"):
https://www.ryadel.com/en/get-file-content-mime-type-from-extension-asp-net-mvc-core/
You can simply use it like that:
var mineType=
MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(submitted));
https://www.nuget.org/packages/MimeTypesMap/ is a great NuGet package for this. Use it like this:
MimeTypesMap.GetMimeType("filename.jpeg"); // => image/jpeg
or the other way:
MimeTypesMap.GetExtension("image/jpeg"); // => jpeg
I want to write a console or Click Once WinForms app that will programmatically stop and/or start a windows service on a remote box.
Both boxes are running .NET 3.5 - what .NET API's are available to accomplish this?
in C#:
var sc = new System.ServiceProcess.ServiceController("MyService", "MyRemoteMachine");
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
You can also do this from a command console using the sc command:
sc <server> start [service name]
sc <server> stop [service name]
Use
sc <server> query | find "SERVICE_NAME"
to get a list of service names.
The option <server> has the form \\ServerName
Example
sc \\MyServer stop schedule will stop the Scheduler service.
ServiceController.
You need to have permission to administer the services on the remote box.
As Mehrdad says, you can also use WMI. Both methods work for start and stop, but WMI requires more coding and will give you more access to other resources
If you don't want to code it yourself, PsService by Microsoft/Sysinternals is a command line tool that does what you want.
You can use System.Management APIs (WMI) to control services remotely. WMI is the generic API to do administrative tasks.
For this problem, however, I suggest you to use the easier to use System.ServiceProcess.ServiceController class.
if you need to get the name of the Service:
run this from the command line:
sc query
You will see for example, that SQL Server's service name is 'MSSQL$SQLEXPRESS'.
So to stop the SQL Server service in C#:
ServiceController controller = new ServiceController();
controller.MachineName = "Machine1";
controller.ServiceName = "MSSQL$SQLEXPRESS";
if(controller.Status == ServiceControllerStatus.Running)
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
galets code snippet above is a great start. However, keep in mind it assumes that the service has already started, or, more importantly, that
sc.Status == System.ServiceProcess.ServiceControllerStatus.Running
Also, it may important to, at some point during code execution, call
sc.Refresh();
because the properties values (such as ServiceControllerStatus) may not reflect the actual properties of the service.
For instance, you may call
sc.Start();
and wait indefinitely when this command executes
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running)
Here is a version of this code that I coded with those considerations in mind.
//Restart Content Service on DEV.
String svcName = "TheServiceName";
String machineName = "TheMachineName";
var sc = new System.ServiceProcess.ServiceController(svcName, machineName);
Console.WriteLine("Stopping Service '{0}' on machine '{1}", svcName, machineName);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
//sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
do
{
try
{
sc.Refresh();
if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
Console.WriteLine("Code has detected that servive start is pending, waiting 5 seconds to see if status changes..");
System.Threading.Thread.Sleep(5000);
}
else
{
Console.WriteLine("waiting 5 seconds and retrying start..");
System.Threading.Thread.Sleep(5000);
Console.WriteLine("Attempt Starting Service '{0}' on machine '{1}", svcName, machineName);
sc.Start();
}
}
catch(Exception ex)
{
//If it is already running, then abort do while
if (ex.InnerException.Message == "An instance of the service is already running")
{
Console.WriteLine(ex.InnerException.Message);
continue;
}
Console.WriteLine(ex.InnerException.ToString());
}
} while (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running);
I have done like below:
Note:
If you didn't start your service if you are trying to stop it will throw exception.
If you configure these things in your web.config ,configuration related exception will not come. No need to do anything in IIS.
In Web.Config under <configuration>
<appSettings>
<add key="ServiceName" value="YourServiceName" />
<add key="MachineName" value="YourMachineName" />
</appSettings>
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true" userName="YourUserName" password="YourPassword"/>
</system.web>
In My Service Class:
private void RestartService()
{
string serviceName = System.Configuration.ConfigurationSettings.AppSettings["ServiceName"];
string machineName = System.Configuration.ConfigurationSettings.AppSettings["MachineName"];
try
{
var service = new ServiceController(serviceName, machineName);
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
}
catch (Exception)
{
}
}
Hope this Helps.
Here is a ServiceExtension that can Start and Stop Services on remote pc's.
And it can set the Startup type of the service, even to "automatic (delayed)"
modified version from this Answer to work on remote machines.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.ServiceProcess;
namespace Helpers
{
public enum ServiceStartModeEx
{
Automatic = 2,
Manual = 3,
Disabled = 4,
DelayedAutomatic = 99
}
/// <summary>
/// Extensions to the ServiceController class.
/// </summary>
public static class ServiceControlerExtensions
{
/// <summary>
/// Set the start mode for the service.
/// </summary>
/// <param name="serviceController">The service controller.</param>
/// <param name="mode">The desired start mode.</param>
public static void SetStartMode(this ServiceController serviceController, ServiceStartModeEx mode)
{
IntPtr serviceManagerHandle = OpenServiceManagerHandle(serviceController);
IntPtr serviceHandle = OpenServiceHandle(serviceController, serviceManagerHandle);
try
{
if (mode == ServiceStartModeEx.DelayedAutomatic)
{
ChangeServiceStartType(serviceHandle, ServiceStartModeEx.Automatic);
ChangeDelayedAutoStart(serviceHandle, true);
}
else
{
// Delayed auto-start overrides other settings, so it must be set first.
ChangeDelayedAutoStart(serviceHandle, false);
ChangeServiceStartType(serviceHandle, mode);
}
}
finally
{
if (serviceHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceHandle);
}
if (serviceManagerHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceManagerHandle);
}
}
}
private static IntPtr OpenServiceHandle(ServiceController serviceController, IntPtr serviceManagerHandle)
{
var serviceHandle = OpenService(
serviceManagerHandle,
serviceController.ServiceName,
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
if (serviceHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Error");
}
return serviceHandle;
}
private static IntPtr OpenServiceManagerHandle(ServiceController serviceController)
{
var machineName = string.IsNullOrWhiteSpace(serviceController.MachineName)
? null
: serviceController.MachineName;
IntPtr serviceManagerHandle = OpenSCManager(machineName, null, SC_MANAGER_ALL_ACCESS);
if (serviceManagerHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Manager Error");
}
return serviceManagerHandle;
}
private static void ChangeServiceStartType(IntPtr serviceHandle, ServiceStartModeEx mode)
{
bool result = ChangeServiceConfig(
serviceHandle,
SERVICE_NO_CHANGE,
(uint)mode,
SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
null,
null,
null);
if (result == false)
{
ThrowLastWin32Error("Could not change service start type");
}
}
private static void ChangeDelayedAutoStart(IntPtr hService, bool delayed)
{
// Create structure that contains DelayedAutoStart property.
SERVICE_DELAYED_AUTO_START_INFO info = new SERVICE_DELAYED_AUTO_START_INFO();
// Set the DelayedAutostart property in that structure.
info.fDelayedAutostart = delayed;
// Allocate necessary memory.
IntPtr hInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_DELAYED_AUTO_START_INFO)));
// Convert structure to pointer.
Marshal.StructureToPtr(info, hInfo, true);
// Change the configuration.
bool result = ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, hInfo);
// Release memory.
Marshal.FreeHGlobal(hInfo);
if (result == false)
{
ThrowLastWin32Error("Could not set service to delayed automatic");
}
}
private static void ThrowLastWin32Error(string messagePrefix)
{
int nError = Marshal.GetLastWin32Error();
var win32Exception = new Win32Exception(nError);
string message = string.Format("{0}: {1}", messagePrefix, win32Exception.Message);
throw new ExternalException(message);
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr OpenService(
IntPtr hSCManager,
string lpServiceName,
uint dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
SetLastError = true)]
private static extern IntPtr OpenSCManager(
string machineName,
string databaseName,
uint dwAccess);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern Boolean ChangeServiceConfig(
IntPtr hService,
UInt32 nServiceType,
UInt32 nStartType,
UInt32 nErrorControl,
String lpBinaryPathName,
String lpLoadOrderGroup,
IntPtr lpdwTagId,
[In] char[] lpDependencies,
String lpServiceStartName,
String lpPassword,
String lpDisplayName);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ChangeServiceConfig2(
IntPtr hService,
int dwInfoLevel,
IntPtr lpInfo);
[DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
private static extern int CloseServiceHandle(IntPtr hSCObject);
private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
private const uint SERVICE_QUERY_CONFIG = 0x00000001;
private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SERVICE_DELAYED_AUTO_START_INFO
{
public bool fDelayedAutostart;
}
}
}
You can start a service like this
using System.ServiceProcess;
serviceName = "the name of the service"
machineName = "the name of the remote/local host"
var service = new ServiceController(serviceName, machineName);
try
{
service.SetStartMode(ServiceStartModeEx.DelayedAutomatic);
service.Start();
}
finally
{
service.Close();
}
You can stop a service like this
var service = new ServiceController(serviceName, machineName);
try
{
if (service.CanStop)
{
service.SetStartMode(ServiceStartModeEx.Disabled);
service.Stop();
}
}
finally
{
service.Close();
}
To grant a user rights to start and stop a service on a remote pc you have to set some service rights, you can google what subinacl.exe is and where to download it.
C:\Program Files (x86)\Windows Resource Kits\Tools>subinacl.exe /service SERVICENAME /grant=MACHINENAME\USERNAME=F